PERFORCE change 132971 for review

John Baldwin jhb at FreeBSD.org
Thu Jan 10 08:45:25 PST 2008


http://perforce.freebsd.org/chv.cgi?CH=132971

Change 132971 by jhb at jhb_zion on 2008/01/10 16:45:02

	IFC @132967

Affected files ...

.. //depot/projects/power/sys/alpha/include/ioctl_meteor.h#3 delete
.. //depot/projects/power/sys/boot/i386/loader/loader.rc#3 integrate
.. //depot/projects/power/sys/dev/coretemp/coretemp.c#2 integrate
.. //depot/projects/power/sys/dev/lmc/if_lmc.c#3 branch
.. //depot/projects/power/sys/dev/sound/midi/midi.c#3 integrate
.. //depot/projects/power/sys/dev/sound/midi/midi.h#3 integrate
.. //depot/projects/power/sys/dev/sound/midi/sequencer.c#3 integrate
.. //depot/projects/power/sys/dev/sound/midi/sequencer.h#2 integrate
.. //depot/projects/power/sys/modules/pflog/Makefile#3 integrate

Differences ...

==== //depot/projects/power/sys/boot/i386/loader/loader.rc#3 (text+ko) ====


==== //depot/projects/power/sys/dev/coretemp/coretemp.c#2 (text+ko) ====

@@ -23,7 +23,7 @@
  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/coretemp/coretemp.c,v 1.4 2007/10/15 20:00:21 netchild Exp $
+ * $FreeBSD: src/sys/dev/coretemp/coretemp.c,v 1.5 2008/01/10 16:09:22 rpaulo Exp $
  *
  */
 
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/coretemp/coretemp.c,v 1.4 2007/10/15 20:00:21 netchild Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/coretemp/coretemp.c,v 1.5 2008/01/10 16:09:22 rpaulo Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -143,6 +143,11 @@
 	cpu_model += ((cpu_id >> 16) & 0xf) << 4;
 	cpu_mask = cpu_id & 15;
 
+#if 0 /*
+       * XXXrpaulo: I have this CPU model and when it returns from C3
+       * coretemp continues to function properly.
+       */
+	 
 	/*
 	 * Check for errata AE18.
 	 * "Processor Digital Thermal Sensor (DTS) Readout stops
@@ -159,6 +164,7 @@
 			return (ENXIO);
 		}
 	}
+#endif
 	/*
 	 * On some Core 2 CPUs, there's an undocumented MSR that
 	 * can tell us if Tj(max) is 100 or 85.

==== //depot/projects/power/sys/dev/sound/midi/midi.c#3 (text+ko) ====

@@ -1,1054 +1,1528 @@
-/*
- * Main midi driver for FreeBSD. This file provides the main
- * entry points for probe/attach and all i/o demultiplexing, including
- * default routines for generic devices.
- * 
- * (C) 1999 Seigo Tanimura
- * 
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
+/*-
+ * Copyright (c) 2003 Mathew Kanner
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (augustss at netbsd.org).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- *    copyright notice, this list of conditions and the following
- *    disclaimer in the documentation and/or other materials provided
- *    with the distribution.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS
- * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
- * AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ /*
+  * Parts of this file started out as NetBSD: midi.c 1.31
+  * They are mostly gone.  Still the most obvious will be the state
+  * machine midi_in
+  */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/dev/sound/midi/midi.c,v 1.24 2007/04/02 06:03:47 ariff Exp $");
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/conf.h>
+#include <sys/selinfo.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <sys/malloc.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/fcntl.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/poll.h>
+#include <sys/sbuf.h>
+#include <sys/kobj.h>
+#include <sys/module.h>
+
+#include <dev/sound/midi/midi.h>
+#include "mpu_if.h"
+
+#include <dev/sound/midi/midiq.h>
+#include "synth_if.h"
+MALLOC_DEFINE(M_MIDI, "midi buffers", "Midi data allocation area");
+
+
+#define PCMMKMINOR(u, d, c) ((((c) & 0xff) << 16) | (((u) & 0x0f) << 4) | ((d) & 0x0f))
+#define MIDIMKMINOR(u, d, c) PCMMKMINOR(u, d, c)
+
+#define MIDI_DEV_RAW	2
+#define MIDI_DEV_MIDICTL 12
+
+enum midi_states {
+	MIDI_IN_START, MIDI_IN_SYSEX, MIDI_IN_DATA
+};
+
+/*
+ * The MPU interface current has init() uninit() inqsize(( outqsize()
+ * callback() : fiddle with the tx|rx status.
+ */
+
+#include "mpu_if.h"
+
+/*
+ * /dev/rmidi	Structure definitions
+ */
+
+#define MIDI_NAMELEN   16
+struct snd_midi {
+	KOBJ_FIELDS;
+	struct mtx lock;		/* Protects all but queues */
+	void   *cookie;
+
+	int	unit;			/* Should only be used in midistat */
+	int	channel;		/* Should only be used in midistat */
+
+	int	busy;
+	int	flags;			/* File flags */
+	char	name[MIDI_NAMELEN];
+	struct mtx qlock;		/* Protects inq, outq and flags */
+	MIDIQ_HEAD(, char) inq, outq;
+	int	rchan, wchan;
+	struct selinfo rsel, wsel;
+	int	hiwat;			/* QLEN(outq)>High-water -> disable
+					 * writes from userland */
+	enum midi_states inq_state;
+	int	inq_status, inq_left;	/* Variables for the state machine in
+					 * Midi_in, this is to provide that
+					 * signals only get issued only
+					 * complete command packets. */
+	struct proc *async;
+	struct cdev *dev;
+	struct synth_midi *synth;
+	int	synth_flags;
+	TAILQ_ENTRY(snd_midi) link;
+};
+
+struct synth_midi {
+	KOBJ_FIELDS;
+	struct snd_midi *m;
+};
+
+static synth_open_t midisynth_open;
+static synth_close_t midisynth_close;
+static synth_writeraw_t midisynth_writeraw;
+static synth_killnote_t midisynth_killnote;
+static synth_startnote_t midisynth_startnote;
+static synth_setinstr_t midisynth_setinstr;
+static synth_alloc_t midisynth_alloc;
+static synth_controller_t midisynth_controller;
+static synth_bender_t midisynth_bender;
+
+
+static kobj_method_t midisynth_methods[] = {
+	KOBJMETHOD(synth_open, midisynth_open),
+	KOBJMETHOD(synth_close, midisynth_close),
+	KOBJMETHOD(synth_writeraw, midisynth_writeraw),
+	KOBJMETHOD(synth_setinstr, midisynth_setinstr),
+	KOBJMETHOD(synth_startnote, midisynth_startnote),
+	KOBJMETHOD(synth_killnote, midisynth_killnote),
+	KOBJMETHOD(synth_alloc, midisynth_alloc),
+	KOBJMETHOD(synth_controller, midisynth_controller),
+	KOBJMETHOD(synth_bender, midisynth_bender),
+	{0, 0}
+};
+
+DEFINE_CLASS(midisynth, midisynth_methods, 0);
+
+/*
+ * Module Exports & Interface
  *
+ * struct midi_chan *midi_init(MPU_CLASS cls, int unit, int chan) int
+ * midi_uninit(struct snd_midi *) 0 == no error EBUSY or other error int
+ * Midi_in(struct midi_chan *, char *buf, int count) int Midi_out(struct
+ * midi_chan *, char *buf, int count)
  *
- * For each card type a template "mididev_info" structure contains
- * all the relevant parameters, both for configuration and runtime.
+ * midi_{in,out} return actual size transfered
  *
- * In this file we build tables of pointers to the descriptors for
- * the various supported cards. The generic probe routine scans
- * the table(s) looking for a matching entry, then invokes the
- * board-specific probe routine. If successful, a pointer to the
- * correct mididev_info is stored in mididev_last_probed, for subsequent
- * use in the attach routine. The generic attach routine copies
- * the template to a permanent descriptor (midi_info and
- * friends), initializes all generic parameters, and calls the
- * board-specific attach routine.
- *
- * On device calls, the generic routines do the checks on unit and
- * device parameters, then call the board-specific routines if
- * available, or try to perform the task using the default code.
- *
- * $FreeBSD: src/sys/dev/sound/midi/midi.c,v 1.14 2004/02/21 21:10:47 phk Exp $
- *
+ */
+
+
+/*
+ * midi_devs tailq, holder of all rmidi instances protected by midistat_lock
  */
 
-#include <dev/sound/midi/midi.h>
+TAILQ_HEAD(, snd_midi) midi_devs;
+
+/*
+ * /dev/midistat variables and declarations, protected by midistat_lock
+ */
 
-static devclass_t midi_devclass;
+static struct mtx midistat_lock;
+static int      midistat_isopen = 0;
+static struct sbuf midistat_sbuf;
+static int      midistat_bufptr;
+static struct cdev *midistat_dev;
 
-static d_open_t midiopen;
-static d_close_t midiclose;
-static d_ioctl_t midiioctl;
-static d_read_t midiread;
-static d_write_t midiwrite;
-static d_poll_t midipoll;
+/*
+ * /dev/midistat	dev_t declarations
+ */
 
-/* These functions are local. */
 static d_open_t midistat_open;
 static d_close_t midistat_close;
 static d_read_t midistat_read;
-static int midi_initstatus(char *buf, int size);
-static int midi_readstatus(char *buf, int *ptr, struct uio *uio);
+
+static struct cdevsw midistat_cdevsw = {
+	.d_version = D_VERSION,
+	.d_open = midistat_open,
+	.d_close = midistat_close,
+	.d_read = midistat_read,
+	.d_name = "midistat",
+};
+
+
+/*
+ * /dev/rmidi dev_t declarations, struct variable access is protected by
+ * locks contained within the structure.
+ */
+
+static d_open_t midi_open;
+static d_close_t midi_close;
+static d_ioctl_t midi_ioctl;
+static d_read_t midi_read;
+static d_write_t midi_write;
+static d_poll_t midi_poll;
 
-#define CDEV_MAJOR MIDI_CDEV_MAJOR
 static struct cdevsw midi_cdevsw = {
-	.d_version =	D_VERSION,
-	.d_flags =	D_NEEDGIANT,
-	.d_open =	midiopen,
-	.d_close =	midiclose,
-	.d_read =	midiread,
-	.d_write =	midiwrite,
-	.d_ioctl =	midiioctl,
-	.d_poll =	midipoll,
-	.d_name =	"midi",
-	.d_maj =	CDEV_MAJOR,
+	.d_version = D_VERSION,
+	.d_open = midi_open,
+	.d_close = midi_close,
+	.d_read = midi_read,
+	.d_write = midi_write,
+	.d_ioctl = midi_ioctl,
+	.d_poll = midi_poll,
+	.d_name = "rmidi",
 };
 
 /*
- * descriptors for active devices. also used as the public softc
- * of a device.
+ * Prototypes of library functions
  */
-static TAILQ_HEAD(,_mididev_info)	midi_info;
-static int		nmidi, nsynth;
-/* Mutex to protect midi_info, nmidi and nsynth. */
-static struct mtx	midiinfo_mtx;
-static int		midiinfo_mtx_init;
 
-/* These make the buffer for /dev/midistat */
-static int		midistatbusy;
-static char		midistatbuf[4096];
-static int		midistatptr;
+static int      midi_destroy(struct snd_midi *, int);
+static int      midistat_prepare(struct sbuf * s);
+static int      midi_load(void);
+static int      midi_unload(void);
 
+/*
+ * Misc declr.
+ */
 SYSCTL_NODE(_hw, OID_AUTO, midi, CTLFLAG_RD, 0, "Midi driver");
+SYSCTL_NODE(_hw_midi, OID_AUTO, stat, CTLFLAG_RD, 0, "Status device");
 
-int			midi_debug;
+int             midi_debug;
+/* XXX: should this be moved into debug.midi? */
 SYSCTL_INT(_hw_midi, OID_AUTO, debug, CTLFLAG_RW, &midi_debug, 0, "");
 
-midi_cmdtab	cmdtab_midiioctl[] = {
-	{SNDCTL_MIDI_PRETIME,	"SNDCTL_MIDI_PRETIME"},
-	{SNDCTL_MIDI_MPUMODE,	"SNDCTL_MIDI_MPUMODE"},
-	{SNDCTL_MIDI_MPUCMD,	"SNDCTL_MIDI_MPUCMD"},
-	{SNDCTL_SYNTH_INFO,	"SNDCTL_SYNTH_INFO"},
-	{SNDCTL_MIDI_INFO,	"SNDCTL_MIDI_INFO"},
-	{SNDCTL_SYNTH_MEMAVL,	"SNDCTL_SYNTH_MEMAVL"},
-	{SNDCTL_FM_LOAD_INSTR,	"SNDCTL_FM_LOAD_INSTR"},
-	{SNDCTL_FM_4OP_ENABLE,	"SNDCTL_FM_4OP_ENABLE"},
-	{MIOSPASSTHRU,		"MIOSPASSTHRU"},
-	{MIOGPASSTHRU,		"MIOGPASSTHRU"},
-	{AIONWRITE,		"AIONWRITE"},
-	{AIOGSIZE,		"AIOGSIZE"},
-	{AIOSSIZE,		"AIOSSIZE"},
-	{AIOGFMT,		"AIOGFMT"},
-	{AIOSFMT,		"AIOSFMT"},
-	{AIOGMIX,		"AIOGMIX"},
-	{AIOSMIX,		"AIOSMIX"},
-	{AIOSTOP,		"AIOSTOP"},
-	{AIOSYNC,		"AIOSYNC"},
-	{AIOGCAP,		"AIOGCAP"},
-	{-1,			NULL},
-};
+int             midi_dumpraw;
+SYSCTL_INT(_hw_midi, OID_AUTO, dumpraw, CTLFLAG_RW, &midi_dumpraw, 0, "");
+
+int             midi_instroff;
+SYSCTL_INT(_hw_midi, OID_AUTO, instroff, CTLFLAG_RW, &midi_instroff, 0, "");
+
+int             midistat_verbose;
+SYSCTL_INT(_hw_midi_stat, OID_AUTO, verbose, CTLFLAG_RW, 
+	&midistat_verbose, 0, "");
+
+#define MIDI_DEBUG(l,a)	if(midi_debug>=l) a
+/*
+ * CODE START
+ */
 
 /*
- * This is the generic init routine.
- * Must be called after device-specific init.
+ * Register a new rmidi device. cls midi_if interface unit == 0 means
+ * auto-assign new unit number unit != 0 already assigned a unit number, eg.
+ * not the first channel provided by this device. channel,	sub-unit
+ * cookie is passed back on MPU calls Typical device drivers will call with
+ * unit=0, channel=1..(number of channels) and cookie=soft_c and won't care
+ * what unit number is used.
+ *
+ * It is an error to call midi_init with an already used unit/channel combo.
+ *
+ * Returns NULL on error
+ *
  */
-int
-midiinit(mididev_info *d, device_t dev)
+struct snd_midi *
+midi_init(kobj_class_t cls, int unit, int channel, void *cookie)
 {
-	int unit;
+	struct snd_midi *m;
+	int i;
+	int inqsize, outqsize;
+	MIDI_TYPE *buf;
 
+	MIDI_DEBUG(1, printf("midiinit: unit %d/%d.\n", unit, channel));
+	mtx_lock(&midistat_lock);
 	/*
-	 * initialize standard parameters for the device. This can be
-	 * overridden by device-specific configurations but better do
-	 * here the generic things.
+	 * Protect against call with existing unit/channel or auto-allocate a
+	 * new unit number.
 	 */
+	i = -1;
+	TAILQ_FOREACH(m, &midi_devs, link) {
+		mtx_lock(&m->lock);
+		if (unit != 0) {
+			if (m->unit == unit && m->channel == channel) {
+				mtx_unlock(&m->lock);
+				goto err0;
+			}
+		} else {
+			/*
+			 * Find a better unit number
+			 */
+			if (m->unit > i)
+				i = m->unit;
+		}
+		mtx_unlock(&m->lock);
+	}
+
+	if (unit == 0)
+		unit = i + 1;
+
+	MIDI_DEBUG(1, printf("midiinit #2: unit %d/%d.\n", unit, channel));
+	m = malloc(sizeof(*m), M_MIDI, M_NOWAIT | M_ZERO);
+	if (m == NULL)
+		goto err0;
+
+	m->synth = malloc(sizeof(*m->synth), M_MIDI, M_NOWAIT | M_ZERO);
+	kobj_init((kobj_t)m->synth, &midisynth_class);
+	m->synth->m = m;
+	kobj_init((kobj_t)m, cls);
+	inqsize = MPU_INQSIZE(m, cookie);
+	outqsize = MPU_OUTQSIZE(m, cookie);
+
+	MIDI_DEBUG(1, printf("midiinit queues %d/%d.\n", inqsize, outqsize));
+	if (!inqsize && !outqsize)
+		goto err1;
+
+	mtx_init(&m->lock, "raw midi", NULL, 0);
+	mtx_init(&m->qlock, "q raw midi", NULL, 0);
+
+	mtx_lock(&m->lock);
+	mtx_lock(&m->qlock);
+
+	if (inqsize)
+		buf = malloc(sizeof(MIDI_TYPE) * inqsize, M_MIDI, M_NOWAIT);
+	else
+		buf = NULL;
+
+	MIDIQ_INIT(m->inq, buf, inqsize);
+
+	if (outqsize)
+		buf = malloc(sizeof(MIDI_TYPE) * outqsize, M_MIDI, M_NOWAIT);
+	else
+		buf = NULL;
+	m->hiwat = outqsize / 2;
 
-	MIDI_DEBUG(printf("midiinit: unit %d.\n", d->unit));
+	MIDIQ_INIT(m->outq, buf, outqsize);
+
+	if ((inqsize && !MIDIQ_BUF(m->inq)) ||
+	    (outqsize && !MIDIQ_BUF(m->outq)))
+		goto err2;
+
+
+	m->busy = 0;
+	m->flags = 0;
+	m->unit = unit;
+	m->channel = channel;
+	m->cookie = cookie;
+
+	if (MPU_INIT(m, cookie))
+		goto err2;
+
+	mtx_unlock(&m->lock);
+	mtx_unlock(&m->qlock);
+
+	TAILQ_INSERT_TAIL(&midi_devs, m, link);
+
+	mtx_unlock(&midistat_lock);
 
-	unit = d->unit;
-	d->softc = device_get_softc(dev);
-	d->dev = dev;
-	d->magic = MAGIC(d->unit); /* debugging... */
-	d->flags = 0;
-	d->fflags = 0;
-	d->midi_dbuf_in.unit_size = 1;
-	d->midi_dbuf_out.unit_size = 1;
-	d->midi_dbuf_passthru.unit_size = 1;
+	m->dev = make_dev(&midi_cdevsw,
+	    MIDIMKMINOR(unit, MIDI_DEV_RAW, channel),
+	    UID_ROOT, GID_WHEEL, 0666, "midi%d.%d", unit, channel);
+	m->dev->si_drv1 = m;
 
-	mtx_unlock(&d->flagqueue_mtx);
+	return m;
 
-	if (midi_devclass == NULL) {
-		midi_devclass = device_get_devclass(dev);
-		make_dev(&midi_cdevsw, MIDIMKMINOR(0, MIDI_DEV_STATUS),
-			 UID_ROOT, GID_WHEEL, 0444, "midistat");
-	}
-	make_dev(&midi_cdevsw, MIDIMKMINOR(unit, MIDI_DEV_MIDIN),
-		 UID_ROOT, GID_WHEEL, 0666, "midi%d", unit);
+err2:	mtx_destroy(&m->qlock);
+	mtx_destroy(&m->lock);
 
-	return 0 ;
+	if (MIDIQ_BUF(m->inq))
+		free(MIDIQ_BUF(m->inq), M_MIDI);
+	if (MIDIQ_BUF(m->outq))
+		free(MIDIQ_BUF(m->outq), M_MIDI);
+err1:	free(m, M_MIDI);
+err0:	mtx_unlock(&midistat_lock);
+	MIDI_DEBUG(1, printf("midi_init ended in error\n"));
+	return NULL;
 }
 
 /*
- * a small utility function which, given a device number, returns
- * a pointer to the associated mididev_info struct, and sets the unit
- * number.
+ * midi_uninit does not call MIDI_UNINIT, as since this is the implementors
+ * entry point. midi_unint if fact, does not send any methods. A call to
+ * midi_uninit is a defacto promise that you won't manipulate ch anymore
+ *
  */
-mididev_info *
-get_mididev_info(dev_t i_dev, int *unit)
+
+int
+midi_uninit(struct snd_midi *m)
 {
-	int u;
+	int err;
+
+	err = ENXIO;
+	mtx_lock(&midistat_lock);
+	mtx_lock(&m->lock);
+	if (m->busy) {
+		if (!(m->rchan || m->wchan))
+			goto err;
 
-	if (MIDIDEV(i_dev) != MIDI_DEV_MIDIN)
-		return NULL;
-	u = MIDIUNIT(i_dev);
-	if (unit)
-		*unit = u;
+		if (m->rchan) {
+			wakeup(&m->rchan);
+			m->rchan = 0;
+		}
+		if (m->wchan) {
+			wakeup(&m->wchan);
+			m->wchan = 0;
+		}
+	}
+	err = midi_destroy(m, 0);
+	if (!err)
+		goto exit;
 
-	return get_mididev_info_unit(u);
+err:	mtx_unlock(&m->lock);
+exit:	mtx_unlock(&midistat_lock);
+	return err;
 }
 
 /*
- * a small utility function which, given a unit number, returns
- * a pointer to the associated mididev_info struct.
+ * midi_in: process all data until the queue is full, then discards the rest.
+ * Since midi_in is a state machine, data discards can cause it to get out of
+ * whack.  Process as much as possible.  It calls, wakeup, selnotify and
+ * psignal at most once.
  */
-mididev_info *
-get_mididev_info_unit(int unit)
+
+#ifdef notdef
+static int midi_lengths[] = {2, 2, 2, 2, 1, 1, 2, 0};
+
+#endif					/* notdef */
+/* Number of bytes in a MIDI command */
+#define MIDI_LENGTH(d) (midi_lengths[((d) >> 4) & 7])
+#define MIDI_ACK	0xfe
+#define MIDI_IS_STATUS(d) ((d) >= 0x80)
+#define MIDI_IS_COMMON(d) ((d) >= 0xf0)
+
+#define MIDI_SYSEX_START	0xF0
+#define MIDI_SYSEX_END	    0xF7
+
+
+int
+midi_in(struct snd_midi *m, MIDI_TYPE *buf, int size)
 {
-	mididev_info *md;
+	/* int             i, sig, enq; */
+	int used;
+
+	/* MIDI_TYPE       data; */
+	MIDI_DEBUG(5, printf("midi_in: m=%p size=%d\n", m, size));
+
+/*
+ * XXX: locking flub
+ */
+	if (!(m->flags & M_RX))
+		return size;
+
+	used = 0;
+
+	mtx_lock(&m->qlock);
+#if 0
+	/*
+	 * Don't bother queuing if not in read mode.  Discard everything and
+	 * return size so the caller doesn't freak out.
+	 */
+
+	if (!(m->flags & M_RX))
+		return size;
+
+	for (i = sig = 0; i < size; i++) {
+
+		data = buf[i];
+		enq = 0;
+		if (data == MIDI_ACK)
+			continue;
 
-	/* XXX */
-	if (!midiinfo_mtx_init) {
-		midiinfo_mtx_init = 1;
-		mtx_init(&midiinfo_mtx, "midinf", NULL, MTX_DEF);
-		TAILQ_INIT(&midi_info);
-	}
+		switch (m->inq_state) {
+		case MIDI_IN_START:
+			if (MIDI_IS_STATUS(data)) {
+				switch (data) {
+				case 0xf0:	/* Sysex */
+					m->inq_state = MIDI_IN_SYSEX;
+					break;
+				case 0xf1:	/* MTC quarter frame */
+				case 0xf3:	/* Song select */
+					m->inq_state = MIDI_IN_DATA;
+					enq = 1;
+					m->inq_left = 1;
+					break;
+				case 0xf2:	/* Song position pointer */
+					m->inq_state = MIDI_IN_DATA;
+					enq = 1;
+					m->inq_left = 2;
+					break;
+				default:
+					if (MIDI_IS_COMMON(data)) {
+						enq = 1;
+						sig = 1;
+					} else {
+						m->inq_state = MIDI_IN_DATA;
+						enq = 1;
+						m->inq_status = data;
+						m->inq_left = MIDI_LENGTH(data);
+					}
+					break;
+				}
+			} else if (MIDI_IS_STATUS(m->inq_status)) {
+				m->inq_state = MIDI_IN_DATA;
+				if (!MIDIQ_FULL(m->inq)) {
+					used++;
+					MIDIQ_ENQ(m->inq, &m->inq_status, 1);
+				}
+				enq = 1;
+				m->inq_left = MIDI_LENGTH(m->inq_status) - 1;
+			}
+			break;
+			/*
+			 * End of case MIDI_IN_START:
+			 */
 
-	mtx_lock(&midiinfo_mtx);
-	TAILQ_FOREACH(md, &midi_info, md_link) {
-		if (md->unit == unit)
+		case MIDI_IN_DATA:
+			enq = 1;
+			if (--m->inq_left <= 0)
+				sig = 1;/* deliver data */
+			break;
+		case MIDI_IN_SYSEX:
+			if (data == MIDI_SYSEX_END)
+				m->inq_state = MIDI_IN_START;
 			break;
+		}
+
+		if (enq)
+			if (!MIDIQ_FULL(m->inq)) {
+				MIDIQ_ENQ(m->inq, &data, 1);
+				used++;
+			}
+		/*
+	         * End of the state machines main "for loop"
+	         */
+	}
+	if (sig) {
+#endif
+		MIDI_DEBUG(6, printf("midi_in: len %jd avail %jd\n",
+		    (intmax_t)MIDIQ_LEN(m->inq),
+		    (intmax_t)MIDIQ_AVAIL(m->inq)));
+		if (MIDIQ_AVAIL(m->inq) > size) {
+			used = size;
+			MIDIQ_ENQ(m->inq, buf, size);
+		} else {
+			MIDI_DEBUG(4, printf("midi_in: Discarding data qu\n"));
+			mtx_unlock(&m->qlock);
+			return 0;
+		}
+		if (m->rchan) {
+			wakeup(&m->rchan);
+			m->rchan = 0;
+		}
+		selwakeup(&m->rsel);
+		if (m->async) {
+			PROC_LOCK(m->async);
+			psignal(m->async, SIGIO);
+			PROC_UNLOCK(m->async);
+		}
+#if 0
 	}
-	mtx_unlock(&midiinfo_mtx);
-
-	return md;
+#endif
+	mtx_unlock(&m->qlock);
+	return used;
 }
 
 /*
- * a small utility function which, given a unit number, returns
- * a pointer to the associated mididev_info struct with MDT_MIDI.
+ * midi_out: The only clearer of the M_TXEN flag.
  */
-mididev_info *
-get_mididev_midi_unit(int unit)
+int
+midi_out(struct snd_midi *m, MIDI_TYPE *buf, int size)
 {
-	mididev_info *md;
+	int used;
+
+/*
+ * XXX: locking flub
+ */
+	if (!(m->flags & M_TXEN))
+		return 0;
 
-	/* XXX */
-	if (!midiinfo_mtx_init) {
-		midiinfo_mtx_init = 1;
-		mtx_init(&midiinfo_mtx, "midinf", NULL, MTX_DEF);
-		TAILQ_INIT(&midi_info);
+	MIDI_DEBUG(2, printf("midi_out: %p\n", m));
+	mtx_lock(&m->qlock);
+	used = MIN(size, MIDIQ_LEN(m->outq));
+	MIDI_DEBUG(3, printf("midi_out: used %d\n", used));
+	if (used)
+		MIDIQ_DEQ(m->outq, buf, used);
+	if (MIDIQ_EMPTY(m->outq)) {
+		m->flags &= ~M_TXEN;
+		MPU_CALLBACKP(m, m->cookie, m->flags);
 	}
-
-	mtx_lock(&midiinfo_mtx);
-	TAILQ_FOREACH(md, &midi_info, md_link) {
-		if (md->midiunit == unit)
-			break;
+	if (used && MIDIQ_AVAIL(m->outq) > m->hiwat) {
+		if (m->wchan) {
+			wakeup(&m->wchan);
+			m->wchan = 0;
+		}
+		selwakeup(&m->wsel);
+		if (m->async) {
+			PROC_LOCK(m->async);
+			psignal(m->async, SIGIO);
+			PROC_UNLOCK(m->async);
+		}
 	}
-	mtx_unlock(&midiinfo_mtx);
+	mtx_unlock(&m->qlock);
+	return used;
+}
 
-	return md;
-}
 
 /*
- * a small utility function which, given a unit number, returns
- * a pointer to the associated mididev_info struct with MDT_SYNTH.
+ * /dev/rmidi#.#	device access functions
  */
-mididev_info *
-get_mididev_synth_unit(int unit)
+int
+midi_open(struct cdev *i_dev, int flags, int mode, struct thread *td)
 {
-	mididev_info *md;
+	struct snd_midi *m = i_dev->si_drv1;
+	int retval;
+
+	MIDI_DEBUG(1, printf("midiopen %p %s %s\n", td,
+	    flags & FREAD ? "M_RX" : "", flags & FWRITE ? "M_TX" : ""));
+	if (m == NULL)
+		return ENXIO;
+
+	mtx_lock(&m->lock);
+	mtx_lock(&m->qlock);
+
+	retval = 0;
 
-	/* XXX */
-	if (!midiinfo_mtx_init) {
-		midiinfo_mtx_init = 1;
-		mtx_init(&midiinfo_mtx, "midinf", NULL, MTX_DEF);
-		TAILQ_INIT(&midi_info);
+	if (flags & FREAD) {
+		if (MIDIQ_SIZE(m->inq) == 0)
+			retval = ENXIO;
+		else if (m->flags & M_RX)
+			retval = EBUSY;
+		if (retval)
+			goto err;
+	}
+	if (flags & FWRITE) {
+		if (MIDIQ_SIZE(m->outq) == 0)
+			retval = ENXIO;
+		else if (m->flags & M_TX)
+			retval = EBUSY;
+		if (retval)
+			goto err;
 	}
+	m->busy++;
+
+	m->rchan = 0;
+	m->wchan = 0;
+	m->async = 0;
 
-	mtx_lock(&midiinfo_mtx);
-	TAILQ_FOREACH(md, &midi_info, md_link) {
-		if (md->synthunit == unit)
-			break;
-	}
-	mtx_unlock(&midiinfo_mtx);
+	if (flags & FREAD) {
+		m->flags |= M_RX | M_RXEN;
+		/*
+	         * Only clear the inq, the outq might still have data to drain
+	         * from a previous session
+	         */
+		MIDIQ_CLEAR(m->inq);
+	};
+
+	if (flags & FWRITE)
+		m->flags |= M_TX;
+
+	MPU_CALLBACK(m, m->cookie, m->flags);
+
+	MIDI_DEBUG(2, printf("midi_open: opened.\n"));
 
-	return md;
+err:	mtx_unlock(&m->qlock);
+	mtx_unlock(&m->lock);
+	return retval;
 }
 
-/* Create a new midi device info structure. */
-/* TODO: lock md, then exit. */
-mididev_info *
-create_mididev_info_unit(int type, mididev_info *mdinf, synthdev_info *syninf)
+int
+midi_close(struct cdev *i_dev, int flags, int mode, struct thread *td)
 {
-	int unit;
-	mididev_info *md, *mdnew;
+	struct snd_midi *m = i_dev->si_drv1;
+	int retval;
+	int oldflags;
 
-	/* XXX */
-	if (!midiinfo_mtx_init) {
-		midiinfo_mtx_init = 1;
-		mtx_init(&midiinfo_mtx, "midinf", NULL, MTX_DEF);
-		TAILQ_INIT(&midi_info);
-	}
+	MIDI_DEBUG(1, printf("midi_close %p %s %s\n", td,
+	    flags & FREAD ? "M_RX" : "", flags & FWRITE ? "M_TX" : ""));
 
-	/* As malloc(9) might block, allocate mididev_info now. */
-	mdnew = malloc(sizeof(mididev_info), M_DEVBUF, M_WAITOK | M_ZERO);
-	if (mdnew == NULL)
-		return NULL;
-	bcopy(mdinf, mdnew, sizeof(mididev_info));
-	bcopy(syninf, &mdnew->synth, sizeof(synthdev_info));
-	midibuf_init(&mdnew->midi_dbuf_in);
-	midibuf_init(&mdnew->midi_dbuf_out);
-	midibuf_init(&mdnew->midi_dbuf_passthru);
-	mtx_init(&mdnew->flagqueue_mtx, "midflq", NULL, MTX_DEF);
-	mtx_init(&mdnew->synth.vc_mtx, "synsvc", NULL, MTX_DEF);
-	mtx_init(&mdnew->synth.status_mtx, "synsst", NULL, MTX_DEF);
+	if (m == NULL)
+		return ENXIO;
 
-	mtx_lock(&midiinfo_mtx);
+	mtx_lock(&m->lock);
+	mtx_lock(&m->qlock);
 
-	switch (type) {
-	case MDT_MIDI:
-		mdnew->midiunit = nmidi;
-		mdnew->synthunit = nmidi;
-		nmidi++;
-		break;
-	case MDT_SYNTH:
-		mdnew->midiunit = -1;
-		mdnew->synthunit = nsynth;
-		nsynth++;
-		break;
-	default:
-		mtx_unlock(&midiinfo_mtx);
-		midibuf_destroy(&mdnew->midi_dbuf_in);
-		midibuf_destroy(&mdnew->midi_dbuf_out);
-		midibuf_destroy(&mdnew->midi_dbuf_passthru);
-		mtx_destroy(&mdnew->flagqueue_mtx);
-		mtx_destroy(&mdnew->synth.vc_mtx);
-		mtx_destroy(&mdnew->synth.status_mtx);
-		free(mdnew, M_DEVBUF);
-		panic("unsupported device type");
-		return NULL;
+	if ((flags & FREAD && !(m->flags & M_RX)) ||
+	    (flags & FWRITE && !(m->flags & M_TX))) {
+		retval = ENXIO;

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list