xref: /freebsd/sys/dev/sound/midi/midi.c (revision 5521ff5a4d1929056e7ffc982fac3341ca54df7c)
1 /*
2  * Main midi driver for FreeBSD. This file provides the main
3  * entry points for probe/attach and all i/o demultiplexing, including
4  * default routines for generic devices.
5  *
6  * (C) 1999 Seigo Tanimura
7  *
8  * Redistribution and use in source and binary forms, with or
9  * without modification, are permitted provided that the following
10  * conditions are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above
14  *    copyright notice, this list of conditions and the following
15  *    disclaimer in the documentation and/or other materials provided
16  *    with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS
19  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
22  * AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  *
32  * For each card type a template "mididev_info" structure contains
33  * all the relevant parameters, both for configuration and runtime.
34  *
35  * In this file we build tables of pointers to the descriptors for
36  * the various supported cards. The generic probe routine scans
37  * the table(s) looking for a matching entry, then invokes the
38  * board-specific probe routine. If successful, a pointer to the
39  * correct mididev_info is stored in mididev_last_probed, for subsequent
40  * use in the attach routine. The generic attach routine copies
41  * the template to a permanent descriptor (midi_info and
42  * friends), initializes all generic parameters, and calls the
43  * board-specific attach routine.
44  *
45  * On device calls, the generic routines do the checks on unit and
46  * device parameters, then call the board-specific routines if
47  * available, or try to perform the task using the default code.
48  *
49  * $FreeBSD$
50  *
51  */
52 
53 #include <dev/sound/midi/midi.h>
54 
55 static devclass_t midi_devclass;
56 
57 static d_open_t midiopen;
58 static d_close_t midiclose;
59 static d_ioctl_t midiioctl;
60 static d_read_t midiread;
61 static d_write_t midiwrite;
62 static d_poll_t midipoll;
63 
64 /* These functions are local. */
65 static d_open_t midistat_open;
66 static d_close_t midistat_close;
67 static d_read_t midistat_read;
68 static int midi_initstatus(char *buf, int size);
69 static int midi_readstatus(char *buf, int *ptr, struct uio *uio);
70 
71 #define CDEV_MAJOR MIDI_CDEV_MAJOR
72 static struct cdevsw midi_cdevsw = {
73 	/* open */	midiopen,
74 	/* close */	midiclose,
75 	/* read */	midiread,
76 	/* write */	midiwrite,
77 	/* ioctl */	midiioctl,
78 	/* poll */	midipoll,
79 	/* mmap */	nommap,
80 	/* strategy */	nostrategy,
81 	/* name */	"midi",
82 	/* maj */	CDEV_MAJOR,
83 	/* dump */	nodump,
84 	/* psize */	nopsize,
85 	/* flags */	0,
86 };
87 
88 /*
89  * descriptors for active devices. also used as the public softc
90  * of a device.
91  */
92 static TAILQ_HEAD(,_mididev_info) midi_info;
93 static int nmidi, nsynth;
94 /* Mutex to protect midi_info, nmidi and nsynth. */
95 static struct mtx midiinfo_mtx;
96 static int midiinfo_mtx_init;
97 
98 /* These make the buffer for /dev/midistat */
99 static int midistatbusy;
100 static char midistatbuf[4096];
101 static int midistatptr;
102 
103 /*
104  * This is the generic init routine.
105  * Must be called after device-specific init.
106  */
107 int
108 midiinit(mididev_info *d, device_t dev)
109 {
110 	int unit;
111 
112 	/*
113 	 * initialize standard parameters for the device. This can be
114 	 * overridden by device-specific configurations but better do
115 	 * here the generic things.
116 	 */
117 
118 	unit = d->unit;
119 	d->softc = device_get_softc(dev);
120 	d->dev = dev;
121 	d->magic = MAGIC(d->unit); /* debugging... */
122 	d->flags = 0;
123 	d->fflags = 0;
124 	d->midi_dbuf_in.unit_size = 1;
125 	d->midi_dbuf_out.unit_size = 1;
126 	d->midi_dbuf_passthru.unit_size = 1;
127 
128 	mtx_unlock(&d->flagqueue_mtx);
129 
130 	if (midi_devclass == NULL) {
131 		midi_devclass = device_get_devclass(dev);
132 		make_dev(&midi_cdevsw, MIDIMKMINOR(0, MIDI_DEV_STATUS),
133 			 UID_ROOT, GID_WHEEL, 0444, "midistat");
134 	}
135 	make_dev(&midi_cdevsw, MIDIMKMINOR(unit, MIDI_DEV_MIDIN),
136 		 UID_ROOT, GID_WHEEL, 0666, "midi%d", unit);
137 
138 	return 0 ;
139 }
140 
141 /*
142  * a small utility function which, given a device number, returns
143  * a pointer to the associated mididev_info struct, and sets the unit
144  * number.
145  */
146 mididev_info *
147 get_mididev_info(dev_t i_dev, int *unit)
148 {
149 	int u;
150 
151 	if (MIDIDEV(i_dev) != MIDI_DEV_MIDIN)
152 		return NULL;
153 	u = MIDIUNIT(i_dev);
154 	if (unit)
155 		*unit = u;
156 
157 	return get_mididev_info_unit(u);
158 }
159 
160 /*
161  * a small utility function which, given a unit number, returns
162  * a pointer to the associated mididev_info struct.
163  */
164 mididev_info *
165 get_mididev_info_unit(int unit)
166 {
167 	mididev_info *md;
168 
169 	/* XXX */
170 	if (!midiinfo_mtx_init) {
171 		midiinfo_mtx_init = 1;
172 		mtx_init(&midiinfo_mtx, "midinf", MTX_DEF);
173 		TAILQ_INIT(&midi_info);
174 	}
175 
176 	mtx_lock(&midiinfo_mtx);
177 	TAILQ_FOREACH(md, &midi_info, md_link) {
178 		if (md->unit == unit)
179 			break;
180 	}
181 	mtx_unlock(&midiinfo_mtx);
182 
183 	return md;
184 }
185 
186 /* Create a new midi device info structure. */
187 /* TODO: lock md, then exit. */
188 mididev_info *
189 create_mididev_info_unit(int type, mididev_info *mdinf, synthdev_info *syninf)
190 {
191 	int unit;
192 	mididev_info *md, *mdnew;
193 
194 	/* XXX */
195 	if (!midiinfo_mtx_init) {
196 		midiinfo_mtx_init = 1;
197 		mtx_init(&midiinfo_mtx, "midinf", MTX_DEF);
198 		TAILQ_INIT(&midi_info);
199 	}
200 
201 	/* As malloc(9) might block, allocate mididev_info now. */
202 	mdnew = malloc(sizeof(mididev_info), M_DEVBUF, M_WAITOK | M_ZERO);
203 	if (mdnew == NULL)
204 		return NULL;
205 	bcopy(mdinf, mdnew, sizeof(mididev_info));
206 	bcopy(syninf, &mdnew->synth, sizeof(synthdev_info));
207 	midibuf_init(&mdnew->midi_dbuf_in);
208 	midibuf_init(&mdnew->midi_dbuf_out);
209 	midibuf_init(&mdnew->midi_dbuf_passthru);
210 	mtx_init(&mdnew->flagqueue_mtx, "midflq", MTX_DEF);
211 	mtx_init(&mdnew->synth.vc_mtx, "synsvc", MTX_DEF);
212 	mtx_init(&mdnew->synth.status_mtx, "synsst", MTX_DEF);
213 
214 	mtx_lock(&midiinfo_mtx);
215 
216 	/* XXX midi_info is still static. */
217 	switch (type) {
218 	case MDT_MIDI:
219 		nmidi++;
220 		break;
221 	case MDT_SYNTH:
222 		nsynth++;
223 		break;
224 	default:
225 		mtx_unlock(&midiinfo_mtx);
226 		midibuf_destroy(&mdnew->midi_dbuf_in);
227 		midibuf_destroy(&mdnew->midi_dbuf_out);
228 		midibuf_destroy(&mdnew->midi_dbuf_passthru);
229 		mtx_destroy(&mdnew->flagqueue_mtx);
230 		mtx_destroy(&mdnew->synth.vc_mtx);
231 		mtx_destroy(&mdnew->synth.status_mtx);
232 		free(mdnew, M_DEVBUF);
233 		panic("unsupported device type");
234 		return NULL;
235 	}
236 
237 	for (unit = 0 ; ; unit++) {
238 		TAILQ_FOREACH(md, &midi_info, md_link) {
239 			if (md->unit == unit)
240 				break;
241 		}
242 		if (md == NULL)
243 			break;
244 	}
245 
246 	mdnew->unit = unit;
247 	mtx_lock(&mdnew->flagqueue_mtx);
248 	TAILQ_INSERT_TAIL(&midi_info, mdnew, md_link);
249 
250 	mtx_unlock(&midiinfo_mtx);
251 
252 	return mdnew;
253 }
254 
255 /* Return the number of configured devices. */
256 int
257 mididev_info_number(void)
258 {
259 	return nmidi + nsynth;
260 }
261 
262 /*
263  * here are the switches for the main functions. The switches do
264  * all necessary checks on the device number to make sure
265  * that the device is configured. They also provide some default
266  * functionalities so that device-specific drivers have to deal
267  * only with special cases.
268  */
269 
270 static int
271 midiopen(dev_t i_dev, int flags, int mode, struct proc * p)
272 {
273 	int ret;
274 
275 	switch (MIDIDEV(i_dev)) {
276 	case MIDI_DEV_MIDIN:
277 		ret = midi_open(i_dev, flags, mode, p);
278 		break;
279 	case MIDI_DEV_STATUS:
280 		ret = midistat_open(i_dev, flags, mode, p);
281 		break;
282 	default:
283 		ret = ENXIO;
284 		break;
285 	}
286 
287 	return (ret);
288 }
289 
290 static int
291 midiclose(dev_t i_dev, int flags, int mode, struct proc * p)
292 {
293 	int ret;
294 
295 	switch (MIDIDEV(i_dev)) {
296 	case MIDI_DEV_MIDIN:
297 		ret = midi_close(i_dev, flags, mode, p);
298 		break;
299 	case MIDI_DEV_STATUS:
300 		ret = midistat_close(i_dev, flags, mode, p);
301 		break;
302 	default:
303 		ret = ENXIO;
304 		break;
305 	}
306 
307 	return (ret);
308 }
309 
310 static int
311 midiread(dev_t i_dev, struct uio * buf, int flag)
312 {
313 	int ret;
314 
315 	switch (MIDIDEV(i_dev)) {
316 	case MIDI_DEV_MIDIN:
317 		ret = midi_read(i_dev, buf, flag);
318 		break;
319 	case MIDI_DEV_STATUS:
320 		ret = midistat_read(i_dev, buf, flag);
321 		break;
322 	default:
323 		ret = ENXIO;
324 		break;
325 	}
326 
327 	return (ret);
328 }
329 
330 static int
331 midiwrite(dev_t i_dev, struct uio * buf, int flag)
332 {
333 	int ret;
334 
335 	switch (MIDIDEV(i_dev)) {
336 	case MIDI_DEV_MIDIN:
337 		ret = midi_write(i_dev, buf, flag);
338 		break;
339 	default:
340 		ret = ENXIO;
341 		break;
342 	}
343 
344 	return (ret);
345 }
346 
347 static int
348 midiioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct proc * p)
349 {
350 	int ret;
351 
352 	switch (MIDIDEV(i_dev)) {
353 	case MIDI_DEV_MIDIN:
354 		ret = midi_ioctl(i_dev, cmd, arg, mode, p);
355 		break;
356 	default:
357 		ret = ENXIO;
358 		break;
359 	}
360 
361 	return (ret);
362 }
363 
364 static int
365 midipoll(dev_t i_dev, int events, struct proc * p)
366 {
367 	int ret;
368 
369 	switch (MIDIDEV(i_dev)) {
370 	case MIDI_DEV_MIDIN:
371 		ret = midi_poll(i_dev, events, p);
372 		break;
373 	default:
374 		ret = ENXIO;
375 		break;
376 	}
377 
378 	return (ret);
379 }
380 
381 /*
382  * Followings are the generic methods in midi drivers.
383  */
384 
385 int
386 midi_open(dev_t i_dev, int flags, int mode, struct proc * p)
387 {
388 	int dev, unit, ret;
389 	mididev_info *d;
390 
391 	dev = minor(i_dev);
392 	d = get_mididev_info(i_dev, &unit);
393 
394 	DEB(printf("open midi%d subdev %d flags 0x%08x mode 0x%08x\n",
395 		   unit, dev & 0xf, flags, mode));
396 
397 	if (d == NULL)
398 		return (ENXIO);
399 
400 	/* Mark this device busy. */
401 	mtx_lock(&d->flagqueue_mtx);
402 	device_busy(d->dev);
403 	if ((d->flags & MIDI_F_BUSY) != 0) {
404 		mtx_unlock(&d->flagqueue_mtx);
405 		DEB(printf("opl_open: unit %d is busy.\n", unit));
406 		return (EBUSY);
407 	}
408 	d->flags |= MIDI_F_BUSY;
409 	d->flags &= ~(MIDI_F_READING | MIDI_F_WRITING);
410 	d->fflags = flags;
411 
412 	/* Init the queue. */
413 	if ((flags & FREAD) != 0)
414 		midibuf_clear(&d->midi_dbuf_in);
415 	if ((flags & FWRITE) != 0) {
416 		midibuf_clear(&d->midi_dbuf_out);
417 		midibuf_clear(&d->midi_dbuf_passthru);
418 	}
419 
420 	mtx_unlock(&d->flagqueue_mtx);
421 
422 	if (d->open == NULL)
423 		ret = 0;
424 	else
425 		ret = d->open(i_dev, flags, mode, p);
426 
427 	return (ret);
428 }
429 
430 int
431 midi_close(dev_t i_dev, int flags, int mode, struct proc * p)
432 {
433 	int dev, unit, ret;
434 	mididev_info *d;
435 
436 	dev = minor(i_dev);
437 	d = get_mididev_info(i_dev, &unit);
438 
439 	DEB(printf("close midi%d subdev %d\n", unit, dev & 0xf));
440 
441 	if (d == NULL)
442 		return (ENXIO);
443 
444 	mtx_lock(&d->flagqueue_mtx);
445 
446 	/* Stop recording and playing. */
447 	if ((d->flags & MIDI_F_READING) != 0)
448 		d->callback(d, MIDI_CB_ABORT | MIDI_CB_RD);
449 	if ((d->flags & MIDI_F_WRITING) != 0)
450 		d->callback(d, MIDI_CB_ABORT | MIDI_CB_WR);
451 
452 	/* Clear the queues. */
453 	if ((d->fflags & FREAD) != 0)
454 		midibuf_clear(&d->midi_dbuf_in);
455 	if ((d->fflags & FWRITE) != 0) {
456 		midibuf_clear(&d->midi_dbuf_out);
457 		midibuf_clear(&d->midi_dbuf_passthru);
458 	}
459 
460 	/* Stop playing and unmark this device busy. */
461 	d->flags &= ~MIDI_F_BUSY;
462 	d->fflags = 0;
463 
464 	device_unbusy(d->dev);
465 
466 	mtx_unlock(&d->flagqueue_mtx);
467 
468 	if (d->close == NULL)
469 		ret = 0;
470 	else
471 		ret = d->close(i_dev, flags, mode, p);
472 
473 	return (ret);
474 }
475 
476 int
477 midi_read(dev_t i_dev, struct uio * buf, int flag)
478 {
479 	int dev, unit, len, ret;
480 	mididev_info *d ;
481 
482 	dev = minor(i_dev);
483 
484 	d = get_mididev_info(i_dev, &unit);
485 	DEB(printf("read midi%d subdev %d flag 0x%08x\n", unit, dev & 0xf, flag));
486 
487 	if (d == NULL)
488 		return (ENXIO);
489 
490 	ret = 0;
491 
492 	mtx_lock(&d->flagqueue_mtx);
493 
494 	/* Begin recording. */
495 	d->callback(d, MIDI_CB_START | MIDI_CB_RD);
496 
497 	len = 0;
498 
499 	/* Have we got the data to read? */
500 	if ((d->flags & MIDI_F_NBIO) != 0 && d->midi_dbuf_in.rl == 0)
501 		ret = EAGAIN;
502 	else {
503 		len = buf->uio_resid;
504 		ret = midibuf_uioread(&d->midi_dbuf_in, buf, len, &d->flagqueue_mtx);
505 		if (ret < 0)
506 			ret = -ret;
507 		else
508 			ret = 0;
509 	}
510 
511 	mtx_unlock(&d->flagqueue_mtx);
512 
513 	return (ret);
514 }
515 
516 int
517 midi_write(dev_t i_dev, struct uio * buf, int flag)
518 {
519 	int dev, unit, len, ret;
520 	mididev_info *d;
521 
522 	dev = minor(i_dev);
523 	d = get_mididev_info(i_dev, &unit);
524 
525 	DEB(printf("write midi%d subdev %d flag 0x%08x\n", unit, dev & 0xf, flag));
526 
527 	if (d == NULL)
528 		return (ENXIO);
529 
530 	ret = 0;
531 
532 	mtx_lock(&d->flagqueue_mtx);
533 
534 	/* Have we got the data to write? */
535 	if ((d->flags & MIDI_F_NBIO) != 0 && d->midi_dbuf_out.fl == 0) {
536 		/* Begin playing. */
537 		d->callback(d, MIDI_CB_START | MIDI_CB_WR);
538 		ret = EAGAIN;
539 	} else {
540 		len = buf->uio_resid;
541 		if (len > d->midi_dbuf_out.fl &&
542 		    (d->flags & MIDI_F_NBIO))
543 			len = d->midi_dbuf_out.fl;
544 		ret = midibuf_uiowrite(&d->midi_dbuf_out, buf, len, &d->flagqueue_mtx);
545 		if (ret < 0)
546 			ret = -ret;
547 		else {
548 			/* Begin playing. */
549 			d->callback(d, MIDI_CB_START | MIDI_CB_WR);
550 			ret = 0;
551 		}
552 	}
553 
554 	mtx_unlock(&d->flagqueue_mtx);
555 
556 	return (ret);
557 }
558 
559 /*
560  * generic midi ioctl. Functions of the default driver can be
561  * overridden by the device-specific ioctl call.
562  * If a device-specific call returns ENOSYS (Function not implemented),
563  * the default driver is called. Otherwise, the returned value
564  * is passed up.
565  *
566  * The default handler, for many parameters, sets the value in the
567  * descriptor, sets MIDI_F_INIT, and calls the callback function with
568  * reason INIT. If successful, the callback returns 1 and the caller
569  * can update the parameter.
570  */
571 
572 int
573 midi_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct proc * p)
574 {
575 	int ret = ENOSYS, dev, unit;
576 	mididev_info *d;
577 	struct snd_size *sndsize;
578 
579 	dev = minor(i_dev);
580 	d = get_mididev_info(i_dev, &unit);
581 
582 	if (d == NULL)
583 		return (ENXIO);
584 
585 	if (d->ioctl)
586 		ret = d->ioctl(i_dev, cmd, arg, mode, p);
587 	if (ret != ENOSYS)
588 		return ret;
589 
590 	/*
591 	 * pass control to the default ioctl handler. Set ret to 0 now.
592 	 */
593 	ret = 0;
594 
595 	/*
596 	 * all routines are called with int. blocked. Make sure that
597 	 * ints are re-enabled when calling slow or blocking functions!
598 	 */
599 	switch(cmd) {
600 
601 		/*
602 		 * we start with the new ioctl interface.
603 		 */
604 	case AIONWRITE:	/* how many bytes can write ? */
605 		*(int *)arg = d->midi_dbuf_out.fl;
606 		break;
607 
608 	case AIOSSIZE:     /* set the current blocksize */
609 		sndsize = (struct snd_size *)arg;
610 		mtx_lock(&d->flagqueue_mtx);
611 		if (sndsize->play_size <= d->midi_dbuf_out.unit_size && sndsize->rec_size <= d->midi_dbuf_in.unit_size) {
612 			d->midi_dbuf_out.blocksize = d->midi_dbuf_out.unit_size;
613 			d->midi_dbuf_in.blocksize = d->midi_dbuf_in.unit_size;
614 			sndsize->play_size = d->midi_dbuf_out.blocksize;
615 			sndsize->rec_size = d->midi_dbuf_in.blocksize;
616 			d->flags &= ~MIDI_F_HAS_SIZE;
617 			mtx_unlock(&d->flagqueue_mtx);
618 		}
619 		else {
620 			if (sndsize->play_size > d->midi_dbuf_out.bufsize / 4)
621 				sndsize->play_size = d->midi_dbuf_out.bufsize / 4;
622 			if (sndsize->rec_size > d->midi_dbuf_in.bufsize / 4)
623 				sndsize->rec_size = d->midi_dbuf_in.bufsize / 4;
624 			/* Round up the size to the multiple of EV_SZ. */
625 			d->midi_dbuf_out.blocksize =
626 			    ((sndsize->play_size + d->midi_dbuf_out.unit_size - 1)
627 			     / d->midi_dbuf_out.unit_size) * d->midi_dbuf_out.unit_size;
628 			d->midi_dbuf_in.blocksize =
629 			    ((sndsize->rec_size + d->midi_dbuf_in.unit_size - 1)
630 			     / d->midi_dbuf_in.unit_size) * d->midi_dbuf_in.unit_size;
631 			sndsize->play_size = d->midi_dbuf_out.blocksize;
632 			sndsize->rec_size = d->midi_dbuf_in.blocksize;
633 			d->flags |= MIDI_F_HAS_SIZE;
634 			mtx_unlock(&d->flagqueue_mtx);
635 		}
636 
637 		ret = 0;
638 		break;
639 
640 	case AIOGSIZE:	/* get the current blocksize */
641 		sndsize = (struct snd_size *)arg;
642 		mtx_lock(&d->flagqueue_mtx);
643 		sndsize->play_size = d->midi_dbuf_out.blocksize;
644 		sndsize->rec_size = d->midi_dbuf_in.blocksize;
645 		mtx_unlock(&d->flagqueue_mtx);
646 
647 		ret = 0;
648 		break;
649 
650 	case AIOSTOP:
651 		mtx_lock(&d->flagqueue_mtx);
652 		if (*(int *)arg == AIOSYNC_PLAY) /* play */
653 			*(int *)arg = d->callback(d, MIDI_CB_STOP | MIDI_CB_WR);
654 		else if (*(int *)arg == AIOSYNC_CAPTURE)
655 			*(int *)arg = d->callback(d, MIDI_CB_STOP | MIDI_CB_RD);
656 		else {
657 			DEB(printf("AIOSTOP: bad channel 0x%x\n", *(int *)arg));
658 			*(int *)arg = 0 ;
659 		}
660 		mtx_unlock(&d->flagqueue_mtx);
661 		break ;
662 
663 	case AIOSYNC:
664 		DEB(printf("AIOSYNC chan 0x%03lx pos %lu unimplemented\n",
665 			   ((snd_sync_parm *)arg)->chan,
666 			   ((snd_sync_parm *)arg)->pos));
667 		break;
668 		/*
669 		 * here follow the standard ioctls (filio.h etc.)
670 		 */
671 	case FIONREAD: /* get # bytes to read */
672 		*(int *)arg = d->midi_dbuf_in.rl;
673 		break;
674 
675 	case FIOASYNC: /*set/clear async i/o */
676 		DEB( printf("FIOASYNC\n") ; )
677 		    break;
678 
679 	case FIONBIO: /* set/clear non-blocking i/o */
680 		mtx_lock(&d->flagqueue_mtx);
681 		if ( *(int *)arg == 0 )
682 			d->flags &= ~MIDI_F_NBIO ;
683 		else
684 			d->flags |= MIDI_F_NBIO ;
685 		mtx_unlock(&d->flagqueue_mtx);
686 		break ;
687 
688 	case MIOSPASSTHRU: /* set/clear passthru */
689 		mtx_lock(&d->flagqueue_mtx);
690 		if ( *(int *)arg == 0 )
691 			d->flags &= ~MIDI_F_PASSTHRU ;
692 		else
693 			d->flags |= MIDI_F_PASSTHRU ;
694 
695 		/* Init the queue. */
696 		midibuf_clear(&d->midi_dbuf_passthru);
697 
698 		mtx_unlock(&d->flagqueue_mtx);
699 
700 		/* FALLTHROUGH */
701 	case MIOGPASSTHRU: /* get passthru */
702 		if ((d->flags & MIDI_F_PASSTHRU) != 0)
703 			(int *)arg = 1;
704 		else
705 			(int *)arg = 0;
706 		break ;
707 
708 	default:
709 		DEB(printf("default ioctl midi%d subdev %d fn 0x%08x fail\n",
710 			   unit, dev & 0xf, cmd));
711 		ret = EINVAL;
712 		break ;
713 	}
714 	return ret ;
715 }
716 
717 int
718 midi_poll(dev_t i_dev, int events, struct proc * p)
719 {
720 	int unit, dev, ret, lim;
721 	mididev_info *d;
722 
723 	dev = minor(i_dev);
724 	d = get_mididev_info(i_dev, &unit);
725 
726 	if (d == NULL)
727 		return (ENXIO);
728 
729 	ret = 0;
730 
731 	mtx_lock(&d->flagqueue_mtx);
732 
733 	/* Look up the apropriate queue and select it. */
734 	if ((events & (POLLOUT | POLLWRNORM)) != 0) {
735 		/* Start playing. */
736 		d->callback(d, MIDI_CB_START | MIDI_CB_WR);
737 
738 		/* Find out the boundary. */
739 		if ((d->flags & MIDI_F_HAS_SIZE) != 0)
740 			lim = d->midi_dbuf_out.blocksize;
741 		else
742 			lim = d->midi_dbuf_out.unit_size;
743 		if (d->midi_dbuf_out.fl < lim)
744 			/* No enough space, record select. */
745 			selrecord(p, &d->midi_dbuf_out.sel);
746 		else
747 			/* We can write now. */
748 			ret |= events & (POLLOUT | POLLWRNORM);
749 	}
750 	if ((events & (POLLIN | POLLRDNORM)) != 0) {
751 		/* Start recording. */
752 		d->callback(d, MIDI_CB_START | MIDI_CB_RD);
753 
754 		/* Find out the boundary. */
755 		if ((d->flags & MIDI_F_HAS_SIZE) != 0)
756 			lim = d->midi_dbuf_in.blocksize;
757 		else
758 			lim = d->midi_dbuf_in.unit_size;
759 		if (d->midi_dbuf_in.rl < lim)
760 			/* No data ready, record select. */
761 			selrecord(p, &d->midi_dbuf_in.sel);
762 		else
763 			/* We can write now. */
764 			ret |= events & (POLLIN | POLLRDNORM);
765 	}
766 
767 	mtx_unlock(&d->flagqueue_mtx);
768 
769 	return (ret);
770 }
771 
772 void
773 midi_intr(mididev_info *d)
774 {
775 	if (d->intr != NULL)
776 		d->intr(d->intrarg, d);
777 }
778 
779 /* Flush the output queue. */
780 #define MIDI_SYNC_TIMEOUT 1
781 int
782 midi_sync(mididev_info *d)
783 {
784 	int i, rl;
785 
786 	mtx_assert(&d->flagqueue_mtx, MA_OWNED);
787 
788 	while (d->midi_dbuf_out.rl > 0) {
789 		if ((d->flags & MIDI_F_WRITING) == 0)
790 			d->callback(d, MIDI_CB_START | MIDI_CB_WR);
791 		rl = d->midi_dbuf_out.rl;
792 		i = msleep(&d->midi_dbuf_out.tsleep_out, &d->flagqueue_mtx, PRIBIO | PCATCH, "midsnc", (d->midi_dbuf_out.bufsize * 10 * hz / 38400) + MIDI_SYNC_TIMEOUT * hz);
793 		if (i == EINTR || i == ERESTART) {
794 			if (i == EINTR)
795 				d->callback(d, MIDI_CB_STOP | MIDI_CB_WR);
796 			return (i);
797 		}
798 		if (i == EWOULDBLOCK && rl == d->midi_dbuf_out.rl) {
799 			/* A queue seems to be stuck up. Give up and clear the queue. */
800 			d->callback(d, MIDI_CB_STOP | MIDI_CB_WR);
801 			midibuf_clear(&d->midi_dbuf_out);
802 			return (0);
803 		}
804 	}
805 
806 	return 0;
807 }
808 
809 /*
810  * These handle the status message of the midi drivers.
811  */
812 
813 int
814 midistat_open(dev_t i_dev, int flags, int mode, struct proc * p)
815 {
816 	if (midistatbusy)
817 		return (EBUSY);
818 
819 	bzero(midistatbuf, sizeof(midistatbuf));
820 	midistatptr = 0;
821 	if (midi_initstatus(midistatbuf, sizeof(midistatbuf) - 1))
822 		return (ENOMEM);
823 
824 	midistatbusy = 1;
825 
826 	return (0);
827 }
828 
829 int
830 midistat_close(dev_t i_dev, int flags, int mode, struct proc * p)
831 {
832 	midistatbusy = 0;
833 
834 	return (0);
835 }
836 
837 int
838 midistat_read(dev_t i_dev, struct uio * buf, int flag)
839 {
840 	return midi_readstatus(midistatbuf, &midistatptr, buf);
841 }
842 
843 /*
844  * finally, some "libraries"
845  */
846 
847 /* Inits the buffer for /dev/midistat. */
848 static int
849 midi_initstatus(char *buf, int size)
850 {
851 	int i, p;
852 	device_t dev;
853 	mididev_info *md;
854 
855 	p = 0;
856 	p += snprintf(buf, size, "FreeBSD Midi Driver (newmidi) %s %s\nInstalled devices:\n", __DATE__, __TIME__);
857 	for (i = 0 ; i < mididev_info_number() ; i++) {
858 		md = get_mididev_info_unit(i);
859 		if (!MIDICONFED(md))
860 			continue;
861 		dev = devclass_get_device(midi_devclass, i);
862 		if (p < size)
863 			p += snprintf(&buf[p], size - p, "midi%d: <%s> %s\n", i, device_get_desc(dev), md->midistat);
864 		else
865 			return (1);
866 	}
867 
868 	return (0);
869 }
870 
871 /* Reads the status message. */
872 static int
873 midi_readstatus(char *buf, int *ptr, struct uio *uio)
874 {
875 	int len;
876 
877 	len = min(uio->uio_resid, strlen(&buf[*ptr]));
878 	if (len > 0) {
879 		uiomove(&buf[*ptr], len, uio);
880 		*ptr += len;
881 	}
882 
883 	return (0);
884 }
885