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