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 *);

Reply via email to