Module Name: src
Committed By: christos
Date: Sat Apr 27 22:12:43 UTC 2013
Modified Files:
src/sys/dev: sequencer.c sequencervar.h
Log Message:
allocate dynamically
To generate a diff of this commit:
cvs rdiff -u -r1.55 -r1.56 src/sys/dev/sequencer.c
cvs rdiff -u -r1.15 -r1.16 src/sys/dev/sequencervar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/sequencer.c
diff -u src/sys/dev/sequencer.c:1.55 src/sys/dev/sequencer.c:1.56
--- src/sys/dev/sequencer.c:1.55 Mon Apr 9 06:18:16 2012
+++ src/sys/dev/sequencer.c Sat Apr 27 18:12:42 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: sequencer.c,v 1.55 2012/04/09 10:18:16 plunky Exp $ */
+/* $NetBSD: sequencer.c,v 1.56 2013/04/27 22:12:42 christos Exp $ */
/*
* Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
@@ -55,7 +55,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sequencer.c,v 1.55 2012/04/09 10:18:16 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sequencer.c,v 1.56 2013/04/27 22:12:42 christos Exp $");
#include "sequencer.h"
@@ -117,8 +117,6 @@ typedef union sequencer_pcqitem {
char qi_msg[4];
} sequencer_pcqitem_t;
-struct sequencer_softc seqdevs[NSEQUENCER];
-
void sequencerattach(int);
static void seq_reset(struct sequencer_softc *);
static int seq_do_command(struct sequencer_softc *, seq_event_t *);
@@ -163,26 +161,86 @@ const struct cdevsw sequencer_cdevsw = {
sequencerioctl, nostop, notty, sequencerpoll, nommap,
sequencerkqfilter, D_OTHER | D_MPSAFE
};
+static LIST_HEAD(, sequencer_softc) sequencers = LIST_HEAD_INITIALIZER(sequencers);
+static kmutex_t sequencer_lock;
+
+static void
+sequencerdestroy(struct sequencer_softc *sc) {
+ callout_destroy(&sc->sc_callout);
+ softint_disestablish(sc->sih);
+ cv_destroy(&sc->rchan);
+ cv_destroy(&sc->wchan);
+ cv_destroy(&sc->lchan);
+ if (sc->pcq)
+ pcq_destroy(sc->pcq);
+ kmem_free(sc, sizeof(*sc));
+}
+
+static struct sequencer_softc *
+sequencercreate(int unit) {
+ struct sequencer_softc *sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
+ if (sc == NULL) {
+#ifdef DIAGNOSTIC
+ printf("%s: out of memory\n", __func__);
+#endif
+ return NULL;
+ }
+ sc->sc_unit = unit;
+ callout_init(&sc->sc_callout, CALLOUT_MPSAFE);
+ sc->sih = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE,
+ seq_softintr, sc);
+ mutex_init(&sc->lock, MUTEX_DEFAULT, IPL_NONE);
+ cv_init(&sc->rchan, "midiseqr");
+ cv_init(&sc->wchan, "midiseqw");
+ cv_init(&sc->lchan, "midiseql");
+ sc->pcq = pcq_create(SEQ_MAXQ, KM_SLEEP);
+ if (sc->pcq == NULL) {
+ sequencerdestroy(sc);
+ return NULL;
+ }
+ return sc;
+}
-void
-sequencerattach(int n)
-{
- struct sequencer_softc *sc;
- for (n = 0; n < NSEQUENCER; n++) {
- sc = &seqdevs[n];
- callout_init(&sc->sc_callout, CALLOUT_MPSAFE);
- sc->sih = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE,
- seq_softintr, sc);
- mutex_init(&sc->lock, MUTEX_DEFAULT, IPL_NONE);
- cv_init(&sc->rchan, "midiseqr");
- cv_init(&sc->wchan, "midiseqw");
- cv_init(&sc->lchan, "midiseql");
- sc->pcq = pcq_create(SEQ_MAXQ, KM_SLEEP);
- if (sc->pcq == NULL) {
- panic("sequencerattach");
+static struct sequencer_softc *
+sequencerget(int unit) {
+ struct sequencer_softc *sc;
+ if (unit < 0) {
+#ifdef DIAGNOSTIC
+ panic("%s: unit %d!", __func__, unit);
+#endif
+ return NULL;
+ }
+ mutex_enter(&sequencer_lock);
+ LIST_FOREACH(sc, &sequencers, sc_link) {
+ if (sc->sc_unit == unit) {
+ mutex_exit(&sequencer_lock);
+ return sc;
}
}
+ mutex_exit(&sequencer_lock);
+ if ((sc = sequencercreate(unit)) == NULL)
+ return NULL;
+ mutex_enter(&sequencer_lock);
+ LIST_INSERT_HEAD(&sequencers, sc, sc_link);
+ mutex_exit(&sequencer_lock);
+ return sc;
+}
+
+#ifdef notyet
+static void
+sequencerput(struct sequencer_softc *sc) {
+ mutex_enter(&sequencer_lock);
+ LIST_REMOVE(sc, sc_link);
+ mutex_exit(&sequencer_lock);
+ sequencerdestroy(sc);
+}
+#endif
+
+void
+sequencerattach(int n)
+{
+ mutex_init(&sequencer_lock, MUTEX_DEFAULT, IPL_NONE);
}
/*
@@ -204,14 +262,9 @@ static int
sequencer_enter(dev_t dev, struct sequencer_softc **scp)
{
struct sequencer_softc *sc;
- int unit;
/* First, find the device and take sc_lock. */
- unit = SEQUENCERUNIT(dev);
- if (unit >= NSEQUENCER)
- return (ENXIO);
- sc = &seqdevs[unit];
- if (sc == NULL)
+ if ((sc = sequencerget(SEQUENCERUNIT(dev))) == NULL)
return ENXIO;
mutex_enter(&sc->lock);
while (sc->dvlock) {
@@ -229,23 +282,21 @@ sequencer_enter(dev_t dev, struct sequen
static int
sequenceropen(dev_t dev, int flags, int ifmt, struct lwp *l)
{
- int unit = SEQUENCERUNIT(dev);
struct sequencer_softc *sc;
struct midi_dev *md;
struct midi_softc *msc;
- int error;
+ int error, unit;
DPRINTF(("sequenceropen\n"));
if ((error = sequencer_enter(dev, &sc)) != 0)
return error;
- KASSERT(sc == &seqdevs[unit]);
if (sc->isopen != 0) {
sequencer_exit(sc);
return EBUSY;
}
- if (SEQ_IS_OLD(unit))
+ if (SEQ_IS_OLD(SEQUENCERUNIT(dev)))
sc->mode = SEQ_OLD;
else
sc->mode = SEQ_NEW;
@@ -775,8 +826,10 @@ sequencerioctl(dev_t dev, u_long cmd, vo
static int
sequencerpoll(dev_t dev, int events, struct lwp *l)
{
- struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)];
+ struct sequencer_softc *sc;
int revents = 0;
+ if ((sc = sequencerget(SEQUENCERUNIT(dev))) == NULL)
+ return ENXIO;
DPRINTF(("sequencerpoll: %p events=0x%x\n", sc, events));
@@ -872,8 +925,10 @@ static const struct filterops sequencerw
static int
sequencerkqfilter(dev_t dev, struct knote *kn)
{
- struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)];
+ struct sequencer_softc *sc;
struct klist *klist;
+ if ((sc = sequencerget(SEQUENCERUNIT(dev))) == NULL)
+ return ENXIO;
switch (kn->kn_filter) {
case EVFILT_READ:
Index: src/sys/dev/sequencervar.h
diff -u src/sys/dev/sequencervar.h:1.15 src/sys/dev/sequencervar.h:1.16
--- src/sys/dev/sequencervar.h:1.15 Sat Oct 27 13:18:14 2012
+++ src/sys/dev/sequencervar.h Sat Apr 27 18:12:42 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: sequencervar.h,v 1.15 2012/10/27 17:18:14 chs Exp $ */
+/* $NetBSD: sequencervar.h,v 1.16 2013/04/27 22:12:42 christos Exp $ */
/*
* Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
@@ -104,6 +104,8 @@ struct sequencer_softc {
struct sequencer_queue inq; /* input event queue */
u_long input_stamp;
+ int sc_unit;
+ LIST_ENTRY(sequencer_softc) sc_link;
};
void seq_event_intr(void *, seq_event_t *);