xref: /illumos-gate/usr/src/uts/common/io/audio/impl/audio_sun.c (revision e44e85a7f9935f0428e188393e3da61b17e83884)
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 *, 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, 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 	sc->s_proc = proc;
526 
527 	while (proc->p_oflag & oflag) {
528 
529 		if (oflag & (FNDELAY|FNONBLOCK)) {
530 			rv = EBUSY;
531 			goto failed;
532 		}
533 		if (oflag & FWRITE)
534 			proc->p_info.play.waiting++;
535 		if (oflag & FREAD)
536 			proc->p_info.record.waiting++;
537 		if (cv_wait_sig(&sdev->d_cv, &sdev->d_mx) == 0) {
538 			/* interrupted! */
539 			if (oflag & FWRITE)
540 				proc->p_info.play.waiting--;
541 			if (oflag & FREAD)
542 				proc->p_info.record.waiting--;
543 			rv = EINTR;
544 			goto failed;
545 		}
546 		if (oflag & FWRITE)
547 			proc->p_info.play.waiting--;
548 		if (oflag & FREAD)
549 			proc->p_info.record.waiting--;
550 	}
551 
552 	if (oflag & FWRITE) {
553 		audio_prinfo_t	*play = &proc->p_info.play;
554 		audio_stream_t	*sp = auclnt_output_stream(c);
555 
556 		if (((rv = auclnt_set_rate(sp, 8000)) != 0) ||
557 		    ((rv = auclnt_set_format(sp, AUDIO_FORMAT_ULAW)) != 0) ||
558 		    ((rv = auclnt_set_channels(sp, 1)) != 0)) {
559 			goto failed;
560 		}
561 
562 		auclnt_set_samples(sp, 0);
563 		auclnt_set_errors(sp, 0);
564 		play->eof = 0;
565 		play->buffer_size = 8192;
566 
567 		auclnt_set_gain(sp, ((play->gain * 100) / AUDIO_MAX_GAIN));
568 		auclnt_set_muted(sp, proc->p_info.output_muted);
569 		play->open = B_TRUE;
570 		proc->p_writer = sc;
571 		proc->p_oflag |= FWRITE;
572 	}
573 
574 	if (oflag & FREAD) {
575 		audio_prinfo_t	*rec = &proc->p_info.record;
576 		audio_stream_t	*sp = auclnt_input_stream(c);
577 
578 		if (((rv = auclnt_set_rate(sp, 8000)) != 0) ||
579 		    ((rv = auclnt_set_format(sp, AUDIO_FORMAT_ULAW)) != 0) ||
580 		    ((rv = auclnt_set_channels(sp, 1)) != 0)) {
581 			goto failed;
582 		}
583 
584 		auclnt_set_samples(sp, 0);
585 		auclnt_set_errors(sp, 0);
586 		rec->eof = 0;
587 		rec->buffer_size = 8192;
588 
589 		auclnt_set_gain(sp, ((rec->gain * 100) / AUDIO_MAX_GAIN));
590 		rec->open = B_TRUE;
591 		proc->p_reader = sc;
592 		proc->p_oflag |= FREAD;
593 	}
594 
595 	sproc_update(proc);
596 
597 	mutex_exit(&sdev->d_mx);
598 
599 	return (0);
600 
601 failed:
602 	mutex_exit(&sdev->d_mx);
603 	sproc_release(sc);
604 	return (rv);
605 
606 }
607 
608 static void
609 sun_clear_eof(sclient_t *sc)
610 {
611 	struct eofcnt *eof;
612 	mutex_enter(&sc->s_lock);
613 	while ((eof = list_remove_head(&sc->s_eofcnt)) != NULL) {
614 		kmem_free(eof, sizeof (*eof));
615 	}
616 	mutex_exit(&sc->s_lock);
617 }
618 
619 void
620 sproc_release(sclient_t *sc)
621 {
622 	sproc_t		*proc;
623 	sdev_t		*sdev;
624 	mblk_t		*mp;
625 
626 	proc = sc->s_proc;
627 	sdev = sc->s_sdev;
628 	sc->s_proc = NULL;
629 
630 	mutex_enter(&sdev->d_mx);
631 
632 	if (proc != NULL) {
633 		proc->p_refcnt--;
634 		ASSERT(proc->p_refcnt >= 0);
635 
636 		if (sc == proc->p_writer) {
637 			proc->p_oflag &= ~FWRITE;
638 			proc->p_writer = NULL;
639 		}
640 		if (sc == proc->p_reader) {
641 			proc->p_oflag &= ~FREAD;
642 			proc->p_reader = NULL;
643 		}
644 		cv_broadcast(&sdev->d_cv);
645 
646 		if (proc->p_refcnt == 0) {
647 			list_remove(&sdev->d_procs, proc);
648 			sproc_free(proc);
649 		}
650 		sc->s_proc = NULL;
651 	}
652 
653 	mutex_exit(&sdev->d_mx);
654 
655 	sun_clear_eof(sc);
656 
657 	while ((mp = sc->s_draining) != NULL) {
658 		sc->s_draining = mp->b_next;
659 		mp->b_next = NULL;
660 		freemsg(mp);
661 	}
662 
663 	mutex_destroy(&sc->s_lock);
664 	list_destroy(&sc->s_eofcnt);
665 	kmem_free(sc, sizeof (*sc));
666 }
667 
668 static void
669 sun_sendup(audio_client_t *c)
670 {
671 	audio_stream_t	*sp = auclnt_input_stream(c);
672 	sclient_t	*sc = auclnt_get_private(c);
673 	unsigned	framesz = auclnt_get_framesz(sp);
674 	queue_t		*rq = sc->s_rq;
675 	mblk_t		*mp;
676 	unsigned	nbytes = sc->s_proc->p_info.record.buffer_size;
677 	unsigned	count = nbytes / framesz;
678 
679 	/*
680 	 * Potentially send a message upstream with the record data.
681 	 * We collect this up in chunks of the buffer size requested
682 	 * by the client.
683 	 */
684 
685 	while (auclnt_get_count(sp) >= count) {
686 
687 		if ((!canputnext(rq)) ||
688 		    ((mp = allocb(nbytes, BPRI_MED)) == NULL)) {
689 			/*
690 			 * This will apply back pressure to the
691 			 * buffer.  We haven't yet lost any data, we
692 			 * just can't send it up.  The point at which
693 			 * we have an unrecoverable overrun is in the
694 			 * buffer, not in the streams queue.  So, no
695 			 * need to do anything right now.
696 			 *
697 			 * Note that since recording is enabled, we
698 			 * expect that the callback routine will be
699 			 * called repeatedly & regularly, so we don't
700 			 * have to worry about leaving data orphaned
701 			 * in the queue.
702 			 */
703 			break;
704 		}
705 
706 		(void) auclnt_consume_data(sp, (caddr_t)mp->b_wptr, count);
707 		mp->b_wptr += nbytes;
708 		putnext(rq, mp);
709 	}
710 }
711 
712 static int
713 sun_open(audio_client_t *c, int oflag)
714 {
715 	_NOTE(ARGUNUSED(c));
716 	_NOTE(ARGUNUSED(oflag));
717 	return (0);
718 }
719 
720 static void
721 sun_close(audio_client_t *c)
722 {
723 	_NOTE(ARGUNUSED(c));
724 }
725 
726 static void
727 sproc_update(sproc_t *proc)
728 {
729 	audio_info_t	*info;
730 	audio_stream_t	*sp;
731 	sclient_t	*sc;
732 
733 	info = &proc->p_info;
734 
735 	ASSERT(mutex_owned(&proc->p_sdev->d_mx));
736 
737 	if ((sc = proc->p_writer) != NULL) {
738 		sp = auclnt_output_stream(sc->s_client);
739 
740 		info->play.sample_rate = auclnt_get_rate(sp);
741 		info->play.channels = auclnt_get_channels(sp);
742 		sun_decompose_format(&info->play, auclnt_get_format(sp));
743 
744 		info->play.gain =
745 		    (auclnt_get_gain(sp) * AUDIO_MAX_GAIN) / 100;
746 		info->play.pause = auclnt_is_paused(sp);
747 		info->play.active = !info->play.pause;
748 		info->play.samples = auclnt_get_samples(sp);
749 		info->play.error = auclnt_get_errors(sp) ? B_TRUE : B_FALSE;
750 		info->output_muted = auclnt_get_muted(sp);
751 	}
752 
753 	if ((sc = proc->p_reader) != NULL) {
754 		sp = auclnt_input_stream(sc->s_client);
755 
756 		info->record.sample_rate = auclnt_get_rate(sp);
757 		info->record.channels = auclnt_get_channels(sp);
758 		sun_decompose_format(&info->record, auclnt_get_format(sp));
759 
760 		info->record.gain =
761 		    (auclnt_get_gain(sp) * AUDIO_MAX_GAIN) / 100;
762 		info->record.pause = auclnt_is_paused(sp);
763 		info->record.active = !info->record.pause;
764 		info->record.samples = auclnt_get_samples(sp);
765 		info->record.error = auclnt_get_errors(sp) ? B_TRUE : B_FALSE;
766 	}
767 }
768 
769 static void
770 sioc_getinfo(sioc_t *ip)
771 {
772 	sclient_t	*sc = ip->i_sc;
773 	sproc_t		*proc = sc->s_proc;
774 	int		rv;
775 
776 	switch (ip->i_step) {
777 	case 0:
778 		if ((rv = sioc_alloc(ip, sizeof (audio_info_t))) != 0) {
779 			sioc_error(ip, rv);
780 			break;
781 		}
782 
783 		mutex_enter(&sc->s_sdev->d_mx);
784 		sproc_update(proc);
785 		mutex_exit(&sc->s_sdev->d_mx);
786 
787 		bcopy(&proc->p_info, ip->i_data, sizeof (audio_info_t));
788 		sioc_copyout(ip, sizeof (audio_info_t));
789 		break;
790 	case 1:
791 		sioc_success(ip);
792 		break;
793 	}
794 
795 	ip->i_step++;
796 	sioc_finish(ip);
797 }
798 
799 #define	CHANGED(new, old, field)			\
800 	((new->field != ((uint32_t)~0)) && (new->field != old->field))
801 #define	CHANGED8(new, old, field)			\
802 	((new->field != ((uint8_t)~0)) && (new->field != old->field))
803 
804 static int
805 sun_setinfo(sclient_t *sc, audio_info_t *ninfo)
806 {
807 	sproc_t		*proc = sc->s_proc;
808 	audio_info_t	*oinfo = &proc->p_info;
809 	audio_prinfo_t	*npr;
810 	audio_prinfo_t	*opr;
811 
812 	int		pfmt = AUDIO_FORMAT_NONE;
813 	int		rfmt = AUDIO_FORMAT_NONE;
814 
815 	boolean_t	reader;
816 	boolean_t	writer;
817 	boolean_t	isctl;
818 	audio_stream_t	*sp;
819 	int		rv;
820 
821 	if (auclnt_get_minor_type(sc->s_client) == AUDIO_MINOR_DEVAUDIOCTL) {
822 		/* control node can do both read and write fields */
823 		isctl = B_TRUE;
824 		reader = B_TRUE;
825 		writer = B_TRUE;
826 	} else {
827 		isctl = B_FALSE;
828 		writer = sc == proc->p_writer;
829 		reader = sc == proc->p_reader;
830 	}
831 
832 	/*
833 	 * Start by validating settings.
834 	 */
835 	npr = &ninfo->play;
836 	opr = &oinfo->play;
837 
838 	if (writer && CHANGED(npr, opr, sample_rate)) {
839 		if ((isctl) ||
840 		    (npr->sample_rate < 5500) || (npr->sample_rate > 48000)) {
841 			return (EINVAL);
842 		}
843 	}
844 	if (writer && CHANGED(npr, opr, channels)) {
845 		if ((isctl) || (npr->channels < 1) || (npr->channels > 2)) {
846 			return (EINVAL);
847 		}
848 	}
849 	if (writer &&
850 	    (CHANGED(npr, opr, encoding) || CHANGED(npr, opr, precision))) {
851 		if (npr->encoding == (uint32_t)~0)
852 			npr->encoding = opr->encoding;
853 		if (npr->precision == (uint32_t)~0)
854 			npr->precision = opr->precision;
855 		pfmt = sun_compose_format(npr);
856 		if ((isctl) || (pfmt == AUDIO_FORMAT_NONE)) {
857 			return (EINVAL);
858 		}
859 	}
860 
861 	/* play fields that anyone can modify */
862 	if (CHANGED(npr, opr, gain)) {
863 		if (npr->gain > AUDIO_MAX_GAIN) {
864 			return (EINVAL);
865 		}
866 	}
867 
868 
869 	npr = &ninfo->record;
870 	opr = &oinfo->record;
871 
872 	if (reader && CHANGED(npr, opr, sample_rate)) {
873 		if ((isctl) ||
874 		    (npr->sample_rate < 5500) ||
875 		    (npr->sample_rate > 48000)) {
876 			return (EINVAL);
877 		}
878 	}
879 	if (reader && CHANGED(npr, opr, channels)) {
880 		if ((isctl) || (npr->channels < 1) || (npr->channels > 2)) {
881 			return (EINVAL);
882 		}
883 	}
884 	if (reader &&
885 	    (CHANGED(npr, opr, encoding) || CHANGED(npr, opr, precision))) {
886 		if (npr->encoding == (uint32_t)~0)
887 			npr->encoding = opr->encoding;
888 		if (npr->precision == (uint32_t)~0)
889 			npr->precision = opr->precision;
890 		rfmt = sun_compose_format(npr);
891 		if ((isctl) || (rfmt == AUDIO_FORMAT_NONE)) {
892 			return (EINVAL);
893 		}
894 	}
895 	if (reader && CHANGED(npr, opr, buffer_size)) {
896 		if (isctl) {
897 			return (EINVAL);
898 		}
899 		/* make sure we can support 16-bit stereo samples */
900 		if ((npr->buffer_size % 4) != 0) {
901 			npr->buffer_size = (npr->buffer_size + 3) & ~3;
902 		}
903 		/* limit the maximum buffer size somewhat */
904 		if (npr->buffer_size > 16384) {
905 			npr->buffer_size = 16384;
906 		}
907 	}
908 
909 	/* record fields that anyone can modify */
910 	if (CHANGED(npr, opr, gain)) {
911 		if (npr->gain > AUDIO_MAX_GAIN) {
912 			return (EINVAL);
913 		}
914 	}
915 
916 	/*
917 	 * Now apply the changes.
918 	 */
919 	if (proc->p_writer != NULL) {
920 		sp = auclnt_output_stream(proc->p_writer->s_client);
921 		npr = &ninfo->play;
922 		opr = &oinfo->play;
923 
924 		if (CHANGED(npr, opr, sample_rate)) {
925 			rv = auclnt_set_rate(sp, npr->sample_rate);
926 			if (rv != 0)
927 				return (rv);
928 		}
929 		if (CHANGED(npr, opr, channels)) {
930 			rv = auclnt_set_channels(sp, npr->channels);
931 			if (rv != 0)
932 				return (rv);
933 		}
934 		if (pfmt != AUDIO_FORMAT_NONE) {
935 			rv = auclnt_set_format(sp, pfmt);
936 			if (rv != 0)
937 				return (rv);
938 		}
939 		if (CHANGED(npr, opr, samples)) {
940 			auclnt_set_samples(sp, npr->samples);
941 		}
942 		if (CHANGED(npr, opr, eof)) {
943 			/*
944 			 * This ugly special case code is required to
945 			 * prevent problems with realaudio.
946 			 */
947 			if (npr->eof == 0) {
948 				sun_clear_eof(proc->p_writer);
949 			}
950 			opr->eof = npr->eof;
951 		}
952 		if (CHANGED8(npr, opr, pause)) {
953 			if (npr->pause) {
954 				auclnt_set_paused(sp);
955 			} else {
956 				auclnt_clear_paused(sp);
957 				/* qenable to start up the playback */
958 				qenable(proc->p_writer->s_wq);
959 			}
960 		}
961 		if (CHANGED8(npr, opr, waiting) && (npr->waiting)) {
962 			opr->waiting = npr->waiting;
963 		}
964 		if (CHANGED8(npr, opr, error)) {
965 			auclnt_set_errors(sp, npr->error);
966 		}
967 		if (CHANGED(npr, opr, gain)) {
968 			auclnt_set_gain(sp, (npr->gain * 100) / AUDIO_MAX_GAIN);
969 		}
970 		if (CHANGED8(ninfo, oinfo, output_muted)) {
971 			auclnt_set_muted(sp, ninfo->output_muted);
972 		}
973 		if (CHANGED(npr, opr, buffer_size)) {
974 			/*
975 			 * No checks on the buffer size are performed
976 			 * for play side.  The value of the buffer size
977 			 * is meaningless for play side anyway.
978 			 */
979 			opr->buffer_size = npr->buffer_size;
980 		}
981 	} else {
982 		/* these vaalues are preserved even if /dev/audio not open */
983 		if (CHANGED(npr, opr, gain)) {
984 			opr->gain = npr->gain;
985 		}
986 		if (CHANGED8(ninfo, oinfo, output_muted)) {
987 			oinfo->output_muted = ninfo->output_muted;
988 		}
989 	}
990 
991 	if (proc->p_reader != NULL) {
992 		sp = auclnt_input_stream(proc->p_reader->s_client);
993 		npr = &ninfo->record;
994 		opr = &oinfo->record;
995 
996 		if (CHANGED(npr, opr, sample_rate)) {
997 			rv = auclnt_set_rate(sp, npr->sample_rate);
998 			if (rv != 0)
999 				return (rv);
1000 		}
1001 		if (CHANGED(npr, opr, channels)) {
1002 			rv = auclnt_set_channels(sp, npr->channels);
1003 			if (rv != 0)
1004 				return (rv);
1005 		}
1006 		if (rfmt != AUDIO_FORMAT_NONE) {
1007 			rv = auclnt_set_format(sp, rfmt);
1008 			if (rv != 0)
1009 				return (rv);
1010 		}
1011 		if (CHANGED(npr, opr, samples)) {
1012 			auclnt_set_samples(sp, npr->samples);
1013 		}
1014 		if (CHANGED(npr, opr, eof)) {
1015 			opr->eof = npr->eof;
1016 		}
1017 		if (CHANGED8(npr, opr, pause)) {
1018 			if (npr->pause) {
1019 				auclnt_set_paused(sp);
1020 			} else {
1021 				auclnt_clear_paused(sp);
1022 				auclnt_start(sp);
1023 			}
1024 		}
1025 		if (CHANGED8(npr, opr, waiting) && (npr->waiting)) {
1026 			opr->waiting = npr->waiting;
1027 		}
1028 		if (CHANGED8(npr, opr, error)) {
1029 			auclnt_set_errors(sp, npr->error);
1030 		}
1031 		if (CHANGED(npr, opr, buffer_size)) {
1032 			opr->buffer_size = npr->buffer_size;
1033 		}
1034 		if (CHANGED(npr, opr, gain)) {
1035 			auclnt_set_gain(sp, (npr->gain * 100) / AUDIO_MAX_GAIN);
1036 		}
1037 	} else {
1038 		/* these values are preserved even if /dev/audio not open */
1039 		if (CHANGED(npr, opr, gain)) {
1040 			opr->gain = npr->gain;
1041 		}
1042 	}
1043 
1044 	return (0);
1045 }
1046 
1047 static void
1048 sioc_setinfo(sioc_t *ip)
1049 {
1050 	int		rv;
1051 	sclient_t	*sc = ip->i_sc;
1052 	audio_info_t	*ninfo;
1053 
1054 	switch (ip->i_step) {
1055 	case 0:
1056 		sioc_copyin(ip, sizeof (audio_info_t));
1057 		break;
1058 
1059 	case 1:
1060 		ninfo = (audio_info_t *)ip->i_data;
1061 
1062 		mutex_enter(&sc->s_sdev->d_mx);
1063 		rv = sun_setinfo(ip->i_sc, ninfo);
1064 
1065 		if (rv != 0) {
1066 			sioc_error(ip, rv);
1067 		} else {
1068 			sproc_update(sc->s_proc);
1069 
1070 			bcopy(&sc->s_proc->p_info, ninfo, sizeof (*ninfo));
1071 			sioc_copyout(ip, sizeof (audio_info_t));
1072 		}
1073 		mutex_exit(&sc->s_sdev->d_mx);
1074 		break;
1075 
1076 	case 2:
1077 		sioc_success(ip);
1078 		break;
1079 	}
1080 
1081 	ip->i_step++;
1082 	sioc_finish(ip);
1083 }
1084 
1085 static void
1086 sioc_getdev(sioc_t *ip)
1087 {
1088 	int		rv;
1089 	sclient_t	*sc = ip->i_sc;
1090 	audio_client_t	*c = sc->s_client;
1091 	audio_dev_t	*d = auclnt_get_dev(c);
1092 
1093 	switch (ip->i_step) {
1094 	case 0:
1095 		rv = sioc_alloc(ip, sizeof (audio_device_t));
1096 		if (rv == 0) {
1097 			audio_device_t *a = ip->i_data;
1098 
1099 			(void) snprintf(a->name, sizeof (a->name),
1100 			    "SUNW,%s", auclnt_get_dev_name(d));
1101 			(void) strlcpy(a->config,
1102 			    auclnt_get_dev_description(d), sizeof (a->config));
1103 			(void) strlcpy(a->version,
1104 			    auclnt_get_dev_version(d),  sizeof (a->version));
1105 			sioc_copyout(ip, sizeof (*a));
1106 		} else {
1107 			sioc_error(ip, rv);
1108 		}
1109 		break;
1110 
1111 	case 1:
1112 		sioc_success(ip);
1113 		break;
1114 	}
1115 
1116 	ip->i_step++;
1117 	sioc_finish(ip);
1118 }
1119 
1120 static void
1121 sunstr_ioctl(sioc_t *ip)
1122 {
1123 	switch (ip->i_cmd) {
1124 	case AUDIO_GETINFO:
1125 		sioc_getinfo(ip);
1126 		break;
1127 
1128 	case AUDIO_SETINFO:
1129 		sioc_setinfo(ip);
1130 		break;
1131 
1132 	case AUDIO_GETDEV:
1133 		sioc_getdev(ip);
1134 		break;
1135 
1136 	case AUDIO_DIAG_LOOPBACK:
1137 		/* we don't support this one */
1138 		sioc_error(ip, ENOTTY);
1139 		sioc_finish(ip);
1140 		break;
1141 
1142 	case AUDIO_MIXERCTL_GET_MODE:
1143 	case AUDIO_MIXERCTL_SET_MODE:
1144 	case AUDIO_MIXERCTL_GET_CHINFO:
1145 	case AUDIO_MIXERCTL_SET_CHINFO:
1146 	case AUDIO_MIXERCTL_GETINFO:
1147 	case AUDIO_MIXERCTL_SETINFO:
1148 	case AUDIO_GET_NUM_CHS:
1149 	case AUDIO_GET_CH_NUMBER:
1150 	case AUDIO_GET_CH_TYPE:
1151 	case AUDIO_MIXER_SINGLE_OPEN:
1152 	case AUDIO_MIXER_MULTIPLE_OPEN:
1153 	case AUDIO_MIXER_GET_SAMPLE_RATES:
1154 	default:
1155 		sioc_error(ip, EINVAL);
1156 		sioc_finish(ip);
1157 		break;
1158 	}
1159 }
1160 
1161 static int
1162 sun_sigpoll(audio_client_t *c, void *arg)
1163 {
1164 	sproc_t		*proc = arg;
1165 	sclient_t	*sc;
1166 
1167 	if (auclnt_get_minor_type(c) == AUDIO_MINOR_DEVAUDIOCTL) {
1168 		sc = auclnt_get_private(c);
1169 		/* we only need to notify peers in our own process */
1170 		if ((sc != NULL) && (sc->s_proc == proc)) {
1171 			(void) putnextctl1(sc->s_rq, M_PCSIG, SIGPOLL);
1172 		}
1173 	}
1174 	return (AUDIO_WALK_CONTINUE);
1175 }
1176 
1177 static void
1178 sun_drain(audio_client_t *c)
1179 {
1180 	sclient_t	*sc = auclnt_get_private(c);
1181 	mblk_t		*mplist, *mp;
1182 
1183 	mutex_enter(&sc->s_lock);
1184 	mplist = sc->s_draining;
1185 	sc->s_draining = NULL;
1186 	mutex_exit(&sc->s_lock);
1187 
1188 	while ((mp = mplist) != NULL) {
1189 		mplist = mp->b_next;
1190 		mp->b_next = NULL;
1191 		miocack(sc->s_wq, mp, 0, 0);
1192 	}
1193 }
1194 
1195 static void
1196 sun_output(audio_client_t *c)
1197 {
1198 	sclient_t	*sc = auclnt_get_private(c);
1199 	sproc_t		*proc = sc->s_proc;
1200 	uint64_t	tail;
1201 	struct eofcnt	*eof;
1202 	int		eofs = 0;
1203 
1204 	tail = auclnt_get_tail(auclnt_output_stream(c));
1205 
1206 	/* get more data! (do this early) */
1207 	qenable(sc->s_wq);
1208 
1209 	mutex_enter(&sc->s_lock);
1210 	while (((eof = list_head(&sc->s_eofcnt)) != NULL) &&
1211 	    (eof->tail < tail)) {
1212 		list_remove(&sc->s_eofcnt, eof);
1213 		kmem_free(eof, sizeof (*eof));
1214 		eofs++;
1215 	}
1216 	proc->p_info.play.eof += eofs;
1217 	mutex_exit(&sc->s_lock);
1218 
1219 	if (eofs) {
1220 		auclnt_dev_walk_clients(auclnt_get_dev(c),
1221 		    sun_sigpoll, proc);
1222 	}
1223 }
1224 
1225 static void
1226 sun_input(audio_client_t *c)
1227 {
1228 	sun_sendup(c);
1229 }
1230 
1231 static int
1232 sun_create_minors(audio_dev_t *adev, void *notused)
1233 {
1234 	char		path[MAXPATHLEN];
1235 	minor_t		minor;
1236 	int		inst;
1237 	int		index;
1238 	const char	*driver;
1239 	unsigned	cap;
1240 
1241 	_NOTE(ARGUNUSED(notused));
1242 
1243 	ASSERT(mutex_owned(&sdev_lock));
1244 
1245 	/* don't create device nodes for sndstat device */
1246 	cap = auclnt_get_dev_capab(adev);
1247 	if ((cap & (AUDIO_CLIENT_CAP_PLAY | AUDIO_CLIENT_CAP_RECORD)) == 0) {
1248 		return (AUDIO_WALK_CONTINUE);
1249 	}
1250 
1251 	index = auclnt_get_dev_index(adev);
1252 	inst = auclnt_get_dev_instance(adev);
1253 	driver = auclnt_get_dev_driver(adev);
1254 
1255 	if (sdev_dip != NULL) {
1256 
1257 		minor = AUDIO_MKMN(index, AUDIO_MINOR_DEVAUDIO);
1258 		(void) snprintf(path, sizeof (path), "sound,%s,audio%d",
1259 		    driver, inst);
1260 		(void) ddi_create_minor_node(sdev_dip, path, S_IFCHR, minor,
1261 		    DDI_NT_AUDIO, 0);
1262 
1263 		minor = AUDIO_MKMN(index, AUDIO_MINOR_DEVAUDIOCTL);
1264 		(void) snprintf(path, sizeof (path), "sound,%s,audioctl%d",
1265 		    driver, inst);
1266 		(void) ddi_create_minor_node(sdev_dip, path, S_IFCHR, minor,
1267 		    DDI_NT_AUDIO, 0);
1268 	}
1269 
1270 	return (AUDIO_WALK_CONTINUE);
1271 }
1272 
1273 static int
1274 sun_remove_minors(audio_dev_t *adev, void *notused)
1275 {
1276 	char		path[MAXPATHLEN];
1277 	int		inst;
1278 	const char	*driver;
1279 	unsigned	cap;
1280 
1281 	_NOTE(ARGUNUSED(notused));
1282 
1283 	ASSERT(mutex_owned(&sdev_lock));
1284 
1285 	cap = auclnt_get_dev_capab(adev);
1286 	/* if not a play or record device, don't bother creating minors */
1287 	if ((cap & (AUDIO_CLIENT_CAP_PLAY | AUDIO_CLIENT_CAP_RECORD)) == 0) {
1288 		return (AUDIO_WALK_CONTINUE);
1289 	}
1290 
1291 	inst = auclnt_get_dev_instance(adev);
1292 	driver = auclnt_get_dev_driver(adev);
1293 
1294 	if (sdev_dip != NULL) {
1295 
1296 		(void) snprintf(path, sizeof (path), "sound,%s,audio%d",
1297 		    driver, inst);
1298 		ddi_remove_minor_node(sdev_dip, path);
1299 
1300 		(void) snprintf(path, sizeof (path), "sound,%s,audioctl%d",
1301 		    driver, inst);
1302 		ddi_remove_minor_node(sdev_dip, path);
1303 	}
1304 
1305 	return (AUDIO_WALK_CONTINUE);
1306 }
1307 
1308 static void *
1309 sun_dev_init(audio_dev_t *adev)
1310 {
1311 	sdev_t		*sdev;
1312 	unsigned	cap;
1313 
1314 	cap = auclnt_get_dev_capab(adev);
1315 	/* if not a play or record device, don't bother initializing it */
1316 	if ((cap & (AUDIO_CLIENT_CAP_PLAY | AUDIO_CLIENT_CAP_RECORD)) == 0) {
1317 		return (NULL);
1318 	}
1319 
1320 	sdev = kmem_zalloc(sizeof (*sdev), KM_SLEEP);
1321 	sdev->d_dev = adev;
1322 	mutex_init(&sdev->d_mx, NULL, MUTEX_DRIVER, NULL);
1323 	cv_init(&sdev->d_cv, NULL, CV_DRIVER, NULL);
1324 	list_create(&sdev->d_procs, sizeof (struct sproc),
1325 	    offsetof(struct sproc, p_linkage));
1326 
1327 	mutex_enter(&sdev_lock);
1328 	(void) sun_create_minors(adev, NULL);
1329 	mutex_exit(&sdev_lock);
1330 
1331 	return (sdev);
1332 }
1333 
1334 static void
1335 sun_dev_fini(void *arg)
1336 {
1337 	sdev_t	*sdev = arg;
1338 
1339 	if (sdev != NULL) {
1340 
1341 		/* remove minor nodes */
1342 		mutex_enter(&sdev_lock);
1343 		(void) sun_remove_minors(sdev->d_dev, NULL);
1344 		mutex_exit(&sdev_lock);
1345 
1346 		mutex_destroy(&sdev->d_mx);
1347 		cv_destroy(&sdev->d_cv);
1348 		list_destroy(&sdev->d_procs);
1349 		kmem_free(sdev, sizeof (*sdev));
1350 	}
1351 }
1352 
1353 static struct audio_client_ops sun_ops = {
1354 	"internal,audio",
1355 	sun_dev_init,
1356 	sun_dev_fini,
1357 	sun_open,
1358 	sun_close,
1359 	NULL,	/* read */
1360 	NULL,	/* write */
1361 	NULL,	/* ioctl */
1362 	NULL,	/* chpoll */
1363 	NULL,	/* mmap */
1364 	sun_input,
1365 	sun_output,
1366 	NULL,	/* notify */
1367 	sun_drain,
1368 };
1369 
1370 static struct audio_client_ops sunctl_ops = {
1371 	"internal,audioctl",
1372 	NULL,	/* dev_init */
1373 	NULL,	/* dev_fini */
1374 	sun_open,
1375 	sun_close,
1376 	NULL,	/* read */
1377 	NULL,	/* write */
1378 	NULL,	/* ioctl */
1379 	NULL,	/* chpoll */
1380 	NULL,	/* mmap */
1381 	NULL,	/* output */
1382 	NULL,	/* input */
1383 	NULL,	/* notify */
1384 	NULL,	/* drain */
1385 };
1386 
1387 void
1388 auimpl_sun_init(void)
1389 {
1390 	mutex_init(&sdev_lock, NULL, MUTEX_DRIVER, NULL);
1391 	sdev_dip = NULL;
1392 	auclnt_register_ops(AUDIO_MINOR_DEVAUDIO, &sun_ops);
1393 	auclnt_register_ops(AUDIO_MINOR_DEVAUDIOCTL, &sunctl_ops);
1394 }
1395 
1396 /*
1397  * This is the operations entry points that are streams specific...
1398  * We map "instance" numbers.
1399  */
1400 
1401 static int
1402 sunstr_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *cr)
1403 {
1404 	int			rv;
1405 	minor_t			minor;
1406 	minor_t			index;
1407 	minor_t			type;
1408 	dev_t			physdev;
1409 	ldi_ident_t		lid;
1410 	ldi_handle_t		lh = NULL;
1411 	audio_client_t		*c = NULL;
1412 	sclient_t		*sc = NULL;
1413 	audio_dev_t		*adev;
1414 	unsigned		fmt;
1415 	int			oflag;
1416 	boolean_t		isopen = B_FALSE;
1417 
1418 	if (sflag != 0) {
1419 		/* no direct clone or module opens */
1420 		return (EINVAL);
1421 	}
1422 
1423 	/*
1424 	 * NB: We reuse the partitioning that the core framework is
1425 	 * using for instance numbering.  This does mean that we are
1426 	 * limited to at most AUDIO_MN_INST_MASK devices, but this
1427 	 * number is sufficiently large (8192) that not to be a concern.
1428 	 */
1429 
1430 	minor = getminor(*devp);
1431 	index = (minor >> AUDIO_MN_INST_SHIFT) & AUDIO_MN_INST_MASK;
1432 	type = (minor >> AUDIO_MN_TYPE_SHIFT) & AUDIO_MN_TYPE_MASK;
1433 
1434 	/* can't directly open a cloned node! */
1435 	if (minor & AUDIO_MN_CLONE_MASK) {
1436 		return (ENXIO);
1437 	}
1438 
1439 	switch (type) {
1440 	case AUDIO_MINOR_DEVAUDIOCTL:
1441 		fmt = AUDIO_FORMAT_NONE;
1442 		oflag = flag & ~(FWRITE | FREAD);
1443 		break;
1444 	case AUDIO_MINOR_DEVAUDIO:
1445 		fmt = AUDIO_FORMAT_PCM;
1446 		oflag = flag;
1447 		break;
1448 	default:
1449 		/* these minor types are not legal */
1450 		return (ENXIO);
1451 	}
1452 
1453 	/* look up and hold the matching audio device */
1454 	adev = auclnt_hold_dev_by_index(index);
1455 	if (adev == NULL) {
1456 		return (ENXIO);
1457 	}
1458 	/* find the matching physical devt */
1459 	physdev = makedevice(ddi_driver_major(auclnt_get_dev_devinfo(adev)),
1460 	    AUDIO_MKMN(auclnt_get_dev_instance(adev), type));
1461 
1462 	if ((rv = ldi_ident_from_stream(rq, &lid)) == 0) {
1463 		rv = ldi_open_by_dev(&physdev, OTYP_CHR, flag, cr, &lh, lid);
1464 	}
1465 
1466 	/* ldi open is done, lh holds device, and we can release our hold */
1467 	auclnt_release_dev(adev);
1468 
1469 	if (rv != 0) {
1470 		goto fail;
1471 	}
1472 	/* phys layer clones a device for us */
1473 	ASSERT((getminor(physdev) & AUDIO_MN_CLONE_MASK) != 0);
1474 
1475 	/*
1476 	 * Note: We don't need to retain the hold on the client
1477 	 * structure, because the client is logically "held" by the
1478 	 * open LDI handle.  We're just using this hold_by_devt to
1479 	 * locate the associated client.
1480 	 */
1481 	c = auclnt_hold_by_devt(physdev);
1482 	ASSERT(c != NULL);
1483 	auclnt_release(c);
1484 
1485 	if ((rv = auclnt_open(c, fmt, oflag)) != 0) {
1486 		goto fail;
1487 	}
1488 	isopen = B_TRUE;
1489 
1490 	if ((rv = sproc_hold(c, oflag)) != 0) {
1491 		goto fail;
1492 	}
1493 
1494 	sc = auclnt_get_private(c);
1495 	WR(rq)->q_ptr = rq->q_ptr = sc;
1496 	sc->s_lh = lh;
1497 	sc->s_rq = rq;
1498 	sc->s_wq = WR(rq);
1499 
1500 	/* start up the input */
1501 	if (oflag & FREAD) {
1502 		auclnt_start(auclnt_input_stream(c));
1503 	}
1504 
1505 	/* we just reuse same minor number that phys layer used */
1506 	*devp = makedevice(getmajor(*devp), getminor(physdev));
1507 
1508 	qprocson(rq);
1509 
1510 	return (0);
1511 
1512 fail:
1513 	if (sc != NULL) {
1514 		sproc_release(sc);
1515 	}
1516 	if (isopen) {
1517 		auclnt_close(c);
1518 	}
1519 	if (lh != NULL) {
1520 		(void) ldi_close(lh, flag, cr);
1521 	}
1522 
1523 	return (rv);
1524 }
1525 
1526 static int
1527 sunstr_close(queue_t *rq, int flag, cred_t *cr)
1528 {
1529 	sclient_t	*sc;
1530 	audio_client_t	*c;
1531 	int		rv;
1532 
1533 	sc = rq->q_ptr;
1534 	c = sc->s_client;
1535 
1536 	if ((auclnt_get_minor_type(c) == AUDIO_MINOR_DEVAUDIO) &&
1537 	    (ddi_can_receive_sig() || (ddi_get_pid() == 0))) {
1538 		rv = auclnt_drain(c);
1539 	}
1540 
1541 	auclnt_stop(auclnt_output_stream(c));
1542 	auclnt_stop(auclnt_input_stream(c));
1543 
1544 	auclnt_close(c);
1545 
1546 	qprocsoff(rq);
1547 
1548 	(void) ldi_close(sc->s_lh, flag, cr);
1549 
1550 	sproc_release(sc);
1551 
1552 	return (rv);
1553 }
1554 
1555 static void
1556 sunstr_miocdata(sclient_t *sc, mblk_t *mp)
1557 {
1558 	struct copyresp		*csp;
1559 	sioc_t			*ip;
1560 	mblk_t			*bcont;
1561 
1562 	csp = (void *)mp->b_rptr;
1563 
1564 	/*
1565 	 * If no state, then something "bad" has happened.
1566 	 */
1567 	if (((ip = (void *)csp->cp_private) == NULL) || (ip->i_sc != sc)) {
1568 		miocnak(sc->s_wq, mp, 0, EFAULT);
1569 		return;
1570 	}
1571 
1572 	/*
1573 	 * If we failed to transfer data to/from userland, then we are
1574 	 * done.  (Stream head will have notified userland.)
1575 	 */
1576 	if (csp->cp_rval != 0) {
1577 		ip->i_state = FINI;
1578 		ip->i_mp = mp;
1579 		sioc_finish(ip);
1580 		return;
1581 	}
1582 
1583 	/*
1584 	 * Buffer area for ioctl is attached to chain.
1585 	 * For an ioctl that didn't have any data to copyin,
1586 	 * we might need to allocate a new buffer area.
1587 	 */
1588 	bcont = mp->b_cont;
1589 	ip->i_bcont = bcont;
1590 	mp->b_cont = NULL;
1591 
1592 	if (bcont != NULL) {
1593 		ip->i_data = bcont->b_rptr;
1594 	}
1595 
1596 	/*
1597 	 * Meaty part of data processing.
1598 	 */
1599 	ip->i_state = IOCTL;
1600 	ip->i_mp = mp;
1601 
1602 	/* now, call the handler ioctl */
1603 	sunstr_ioctl(ip);
1604 }
1605 
1606 static void
1607 sunstr_mioctl(sclient_t *sc, mblk_t *mp)
1608 {
1609 	struct iocblk	*iocp = (void *)mp->b_rptr;
1610 	sioc_t		*ip;
1611 
1612 	/* BSD legacy here: we only support transparent ioctls */
1613 	if (iocp->ioc_count != TRANSPARENT) {
1614 		miocnak(sc->s_wq, mp, 0, EINVAL);
1615 		return;
1616 	}
1617 
1618 	ip = kmem_zalloc(sizeof (*ip), KM_NOSLEEP);
1619 	if (ip == NULL) {
1620 		miocnak(sc->s_wq, mp, 0, ENOMEM);
1621 		return;
1622 	}
1623 
1624 	/* make sure everything is setup in case we need to do copyin/out */
1625 	ip->i_sc = sc;
1626 	ip->i_model = iocp->ioc_flag;
1627 	ip->i_cmd = iocp->ioc_cmd;
1628 	ip->i_addr = *(caddr_t *)(void *)mp->b_cont->b_rptr;
1629 	ip->i_state = IOCTL;
1630 	ip->i_mp = mp;
1631 	freemsg(mp->b_cont);
1632 	mp->b_cont = NULL;
1633 
1634 	/* now, call the handler ioctl */
1635 	sunstr_ioctl(ip);
1636 }
1637 
1638 static int
1639 sunstr_wput(queue_t *wq, mblk_t *mp)
1640 {
1641 	sclient_t	*sc = wq->q_ptr;
1642 	struct iocblk	*iocp;
1643 
1644 	switch (DB_TYPE(mp)) {
1645 	case M_IOCTL:
1646 		/* Drain ioctl needs to be handled on the service queue */
1647 		iocp = (void *)mp->b_rptr;
1648 		if (iocp->ioc_cmd == AUDIO_DRAIN) {
1649 			if (auclnt_get_minor_type(sc->s_client) ==
1650 			    AUDIO_MINOR_DEVAUDIO) {
1651 				(void) putq(wq, mp);
1652 			} else {
1653 				miocnak(wq, mp, 0, EINVAL);
1654 			}
1655 		} else {
1656 			sunstr_mioctl(sc, mp);
1657 		}
1658 		break;
1659 
1660 	case M_IOCDATA:
1661 		sunstr_miocdata(sc, mp);
1662 		break;
1663 
1664 	case M_FLUSH:
1665 		/*
1666 		 * We don't flush the engine.  The reason is that
1667 		 * other streams might be using the engine.  This is
1668 		 * fundamentally no different from the case where the
1669 		 * engine hardware has data buffered in an
1670 		 * inaccessible FIFO.
1671 		 *
1672 		 * Clients that want to ensure no more data is coming
1673 		 * should stop the stream before flushing.
1674 		 */
1675 		if (*mp->b_rptr & FLUSHW) {
1676 			flushq(wq, FLUSHALL);
1677 			auclnt_flush(auclnt_output_stream(sc->s_client));
1678 			*mp->b_rptr &= ~FLUSHW;
1679 		}
1680 		if (*mp->b_rptr & FLUSHR) {
1681 			flushq(RD(wq), FLUSHALL);
1682 			auclnt_flush(auclnt_input_stream(sc->s_client));
1683 			qreply(wq, mp);
1684 		} else {
1685 			freemsg(mp);
1686 		}
1687 		break;
1688 
1689 	case M_DATA:
1690 		/*
1691 		 * If we don't have an engine, then we can't accept
1692 		 * write() data.  audio(7i) says we just ignore it,
1693 		 * so we toss it.
1694 		 */
1695 		if (auclnt_get_minor_type(sc->s_client) !=
1696 		    AUDIO_MINOR_DEVAUDIO) {
1697 			freemsg(mp);
1698 		} else {
1699 			/*
1700 			 * Defer processing to the queue.  This keeps
1701 			 * the data ordered, and allows the wsrv
1702 			 * routine to gather multiple mblks at once.
1703 			 */
1704 			if (mp->b_cont != NULL) {
1705 
1706 				/*
1707 				 * If we need to pullup, do it here to
1708 				 * simplify the rest of the processing
1709 				 * later.  This should rarely (if
1710 				 * ever) be necessary.
1711 				 */
1712 				mblk_t	*nmp;
1713 
1714 				if ((nmp = msgpullup(mp, -1)) == NULL) {
1715 					freemsg(mp);
1716 				} else {
1717 					freemsg(mp);
1718 					(void) putq(wq, nmp);
1719 				}
1720 			} else {
1721 				(void) putq(wq, mp);
1722 			}
1723 		}
1724 		break;
1725 
1726 	default:
1727 		freemsg(mp);
1728 		break;
1729 	}
1730 	return (0);
1731 }
1732 
1733 static int
1734 sunstr_wsrv(queue_t *wq)
1735 {
1736 	sclient_t	*sc = wq->q_ptr;
1737 	audio_client_t	*c = sc->s_client;
1738 	audio_stream_t	*sp;
1739 	mblk_t		*mp;
1740 	unsigned	framesz;
1741 
1742 	sp = auclnt_output_stream(c);
1743 
1744 	framesz = auclnt_get_framesz(sp);
1745 
1746 	while ((mp = getq(wq)) != NULL) {
1747 
1748 		unsigned	count;
1749 
1750 		/* got a message */
1751 
1752 		/* if its a drain ioctl, we need to process it here */
1753 		if (DB_TYPE(mp) == M_IOCTL) {
1754 			ASSERT((*(int *)(void *)mp->b_rptr) == AUDIO_DRAIN);
1755 			mutex_enter(&sc->s_lock);
1756 			mp->b_next = sc->s_draining;
1757 			sc->s_draining = mp;
1758 			mutex_exit(&sc->s_lock);
1759 
1760 			if (auclnt_start_drain(c) != 0) {
1761 				sun_drain(c);
1762 			}
1763 			continue;
1764 		}
1765 
1766 		ASSERT(DB_TYPE(mp) == M_DATA);
1767 
1768 		/*
1769 		 * Empty mblk require special handling, since they
1770 		 * indicate EOF.  We treat them separate from the main
1771 		 * processing loop.
1772 		 */
1773 		if (MBLKL(mp) == 0) {
1774 			struct eofcnt	*eof;
1775 
1776 			eof = kmem_zalloc(sizeof (*eof), KM_NOSLEEP);
1777 			if (eof != NULL) {
1778 				eof->tail = auclnt_get_head(sp);
1779 				mutex_enter(&sc->s_lock);
1780 				list_insert_tail(&sc->s_eofcnt, eof);
1781 				mutex_exit(&sc->s_lock);
1782 			}
1783 			freemsg(mp);
1784 			continue;
1785 		}
1786 
1787 		count = auclnt_produce_data(sp, (caddr_t)mp->b_rptr,
1788 		    MBLKL(mp) / framesz);
1789 
1790 		mp->b_rptr += count * framesz;
1791 
1792 		if (MBLKL(mp) >= framesz) {
1793 			(void) putbq(wq, mp);
1794 			break;
1795 		} else {
1796 			freemsg(mp);
1797 		}
1798 	}
1799 
1800 	/* if the stream isn't running yet, start it up */
1801 	if (!auclnt_is_paused(sp))
1802 		auclnt_start(sp);
1803 
1804 	return (0);
1805 }
1806 
1807 static int
1808 sunstr_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1809 {
1810 	if ((cmd != DDI_ATTACH) || (dip == NULL)) {
1811 		return (DDI_FAILURE);
1812 	}
1813 	if (ddi_get_instance(dip) != 0) {
1814 		return (DDI_FAILURE);
1815 	}
1816 
1817 	mutex_enter(&sdev_lock);
1818 	sdev_dip = dip;
1819 	auclnt_walk_devs(sun_create_minors, NULL);
1820 	mutex_exit(&sdev_lock);
1821 	ddi_report_dev(dip);
1822 
1823 	return (0);
1824 }
1825 
1826 static int
1827 sunstr_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1828 {
1829 	if ((cmd != DDI_DETACH) || (dip == NULL)) {
1830 		return (DDI_FAILURE);
1831 	}
1832 	if (ddi_get_instance(dip) != 0) {
1833 		return (DDI_FAILURE);
1834 	}
1835 
1836 	mutex_enter(&sdev_lock);
1837 	/* remove all minors */
1838 	auclnt_walk_devs(sun_remove_minors, NULL);
1839 	sdev_dip = NULL;
1840 	mutex_exit(&sdev_lock);
1841 
1842 	return (0);
1843 }
1844 
1845 static int
1846 sunstr_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
1847 {
1848 	int		error;
1849 
1850 	_NOTE(ARGUNUSED(dip));
1851 	_NOTE(ARGUNUSED(arg));
1852 
1853 	switch (cmd) {
1854 	case DDI_INFO_DEVT2DEVINFO:
1855 		*result = sdev_dip;
1856 		error = DDI_SUCCESS;
1857 		break;
1858 	case DDI_INFO_DEVT2INSTANCE:
1859 		*result = 0;
1860 		error = DDI_SUCCESS;
1861 		break;
1862 	default:
1863 		*result = NULL;
1864 		error = DDI_FAILURE;
1865 	}
1866 	return (error);
1867 }
1868 
1869 static struct module_info sunstr_minfo = {
1870 	0,		/* used for strlog(1M) only, which we don't use */
1871 	"austr",
1872 	0,		/* min pkt size */
1873 	2048,		/* max pkt size */
1874 	65536,		/* hi water */
1875 	32768,		/* lo water */
1876 };
1877 
1878 static struct qinit sunstr_rqinit = {
1879 	NULL,		/* qi_putp */
1880 	NULL,		/* qi_srvp */
1881 	sunstr_open,	/* qi_qopen */
1882 	sunstr_close,	/* qi_qclose */
1883 	NULL,		/* qi_qadmin */
1884 	&sunstr_minfo,	/* qi_minfo */
1885 	NULL,		/* qi_mstat */
1886 };
1887 
1888 static struct qinit sunstr_wqinit = {
1889 	sunstr_wput,	/* qi_putp */
1890 	sunstr_wsrv,	/* qi_srvp */
1891 	NULL,		/* qi_qopen */
1892 	NULL,		/* qi_qclose */
1893 	NULL,		/* qi_qadmin */
1894 	&sunstr_minfo,	/* qi_minfo */
1895 	NULL,		/* qi_mstat */
1896 };
1897 
1898 static struct streamtab sunstr_strtab = {
1899 	&sunstr_rqinit,
1900 	&sunstr_wqinit,
1901 	NULL,
1902 	NULL
1903 };
1904 
1905 struct cb_ops sunstr_cb_ops = {
1906 	nodev,		/* open */
1907 	nodev,		/* close */
1908 	nodev,		/* strategy */
1909 	nodev,		/* print */
1910 	nodev,		/* dump */
1911 	nodev,		/* read */
1912 	nodev,		/* write */
1913 	nodev,		/* ioctl */
1914 	nodev,		/* devmap */
1915 	nodev,		/* mmap */
1916 	nodev,		/* segmap */
1917 	nochpoll,	/* chpoll */
1918 	ddi_prop_op,	/* prop_op */
1919 	&sunstr_strtab,	/* str */
1920 	D_MP,		/* flag */
1921 	CB_REV, 	/* rev */
1922 	nodev,		/* aread */
1923 	nodev,		/* awrite */
1924 };
1925 
1926 static struct dev_ops sunstr_dev_ops = {
1927 	DEVO_REV,		/* rev */
1928 	0,			/* refcnt */
1929 	sunstr_getinfo,		/* getinfo */
1930 	nulldev,		/* identify */
1931 	nulldev,		/* probe */
1932 	sunstr_attach,		/* attach */
1933 	sunstr_detach,		/* detach */
1934 	nodev,			/* reset */
1935 	&sunstr_cb_ops,		/* cb_ops */
1936 	NULL,			/* bus_ops */
1937 	NULL,			/* power */
1938 };
1939 
1940 static struct modldrv sunstr_modldrv = {
1941 	&mod_driverops,
1942 	"Audio Streams Support",
1943 	&sunstr_dev_ops,
1944 };
1945 
1946 static struct modlinkage sunstr_modlinkage = {
1947 	MODREV_1,			/* MODREV_1 indicated by manual */
1948 	&sunstr_modldrv,
1949 	NULL
1950 };
1951 
1952 int
1953 sunstr_init(void)
1954 {
1955 	/*
1956 	 * NB: This *must* be called after the "audio" module's
1957 	 * _init routine has called auimpl_sun_init().
1958 	 */
1959 	return (mod_install(&sunstr_modlinkage));
1960 }
1961 
1962 int
1963 sunstr_fini(void)
1964 {
1965 	return (mod_remove(&sunstr_modlinkage));
1966 }
1967 
1968 int
1969 sunstr_info(struct modinfo *modinfop)
1970 {
1971 	return (mod_info(&sunstr_modlinkage, modinfop));
1972 }
1973