Index: channel.h =================================================================== RCS file: /home/ncvs/src/sys/dev/sound/pcm/channel.h,v retrieving revision 1.26 diff -u -p -r1.26 channel.h --- channel.h 25 Jan 2002 04:14:12 -0000 1.26 +++ channel.h 4 Nov 2002 22:20:15 -0000 @@ -136,6 +136,7 @@ int fmtvalid(u_int32_t fmt, u_int32_t *f #define CHN_F_BADSETTING 0x00040000 #define CHN_F_VIRTUAL 0x10000000 /* not backed by hardware */ +#define CHN_F_NEWDEVICE 0x20000000 #define CHN_F_RESET (CHN_F_BUSY | CHN_F_DEAD | CHN_F_VIRTUAL) Index: dsp.c =================================================================== RCS file: /home/ncvs/src/sys/dev/sound/pcm/dsp.c,v retrieving revision 1.57 diff -u -p -r1.57 dsp.c --- dsp.c 28 Aug 2002 15:19:30 -0000 1.57 +++ dsp.c 4 Nov 2002 22:16:43 -0000 @@ -283,6 +283,7 @@ dsp_open(dev_t i_dev, int flags, int mod if (flags & O_NONBLOCK) rdch->flags |= CHN_F_NBIO; pcm_chnref(rdch, 1); + rdch->flags |= CHN_F_NEWDEVICE; CHN_UNLOCK(rdch); } if (flags & FWRITE) { @@ -302,6 +303,7 @@ dsp_open(dev_t i_dev, int flags, int mod if (flags & O_NONBLOCK) wrch->flags |= CHN_F_NBIO; pcm_chnref(wrch, 1); + wrch->flags |= CHN_F_NEWDEVICE; CHN_UNLOCK(wrch); } splx(s); @@ -315,6 +317,7 @@ dsp_close(dev_t i_dev, int flags, int mo struct snddev_info *d; intrmask_t s; int exit; + int rdch_newdevice = 0, wrch_newdevice = 0; s = spltty(); d = dsp_get_info(i_dev); @@ -327,6 +330,7 @@ dsp_close(dev_t i_dev, int flags, int mo /* decrement refcount for each channel, exit if nonzero */ if (rdch) { CHN_LOCK(rdch); + rdch_newdevice = rdch->flags & CHN_F_NEWDEVICE; if (pcm_chnref(rdch, -1) > 0) { CHN_UNLOCK(rdch); exit = 1; @@ -334,6 +338,7 @@ dsp_close(dev_t i_dev, int flags, int mo } if (wrch) { CHN_LOCK(wrch); + wrch_newdevice = wrch->flags & CHN_F_NEWDEVICE; if (pcm_chnref(wrch, -1) > 0) { CHN_UNLOCK(wrch); exit = 1; @@ -361,12 +366,16 @@ dsp_close(dev_t i_dev, int flags, int mo rdch->flags &= ~(CHN_F_RUNNING | CHN_F_MAPPED | CHN_F_DEAD); chn_reset(rdch, 0); pcm_chnrelease(rdch); + if (rdch_newdevice) + rdch->flags |= CHN_F_NEWDEVICE; } if (wrch) { chn_flush(wrch); /* may sleep */ wrch->flags &= ~(CHN_F_RUNNING | CHN_F_MAPPED | CHN_F_DEAD); chn_reset(wrch, 0); pcm_chnrelease(wrch); + if (wrch_newdevice) + wrch->flags |= CHN_F_NEWDEVICE; } splx(s); Index: sound.c =================================================================== RCS file: /home/ncvs/src/sys/dev/sound/pcm/sound.c,v retrieving revision 1.78 diff -u -p -r1.78 sound.c --- sound.c 4 Nov 2002 19:12:02 -0000 1.78 +++ sound.c 4 Nov 2002 22:12:35 -0000 @@ -31,7 +31,7 @@ #include "feeder_if.h" -SND_DECLARE_FILE("$FreeBSD: src/sys/dev/sound/pcm/sound.c,v 1.78 2002/11/04 19:12:02 cognet Exp $"); +SND_DECLARE_FILE("$FreeBSD: src/sys/dev/sound/pcm/sound.c,v 1.77 2002/08/24 19:13:11 nsayer Exp $"); struct snddev_channel { SLIST_ENTRY(snddev_channel) link; @@ -447,6 +447,7 @@ pcm_chn_add(struct snddev_info *d, struc } if (mkdev) { + sce->channel->flags |= CHN_F_NEWDEVICE; dsp_register(unit, d->devcount++); if (ch->direction == PCMDIR_REC) dsp_registerrec(unit, ch->num); @@ -523,14 +524,14 @@ pcm_killchan(device_t dev) struct snddev_info *d = device_get_softc(dev); struct snddev_channel *sce; struct pcm_channel *ch; - int error = 0; + int error; snd_mtxlock(d->lock); sce = SLIST_FIRST(&d->channels); snd_mtxunlock(d->lock); ch = sce->channel; - error = pcm_chn_remove(d, sce->channel, 1); + error = pcm_chn_remove(d, sce->channel, ch->flags & CHN_F_NEWDEVICE); if (error) return (error); return (pcm_chn_destroy(ch)); Index: vchan.c =================================================================== RCS file: /home/ncvs/src/sys/dev/sound/pcm/vchan.c,v retrieving revision 1.8 diff -u -p -r1.8 vchan.c --- vchan.c 15 Jul 2002 13:03:10 -0000 1.8 +++ vchan.c 4 Nov 2002 22:11:43 -0000 @@ -272,6 +272,7 @@ vchan_create(struct pcm_channel *parent) /* XXX gross ugly hack, kill murder death */ if (first && !err) { + child->flags |= CHN_F_NEWDEVICE; err = chn_reset(parent, AFMT_STEREO | AFMT_S16_LE); if (err) printf("chn_reset: %d\n", err); @@ -317,7 +318,7 @@ gotch: parent->flags &= ~CHN_F_BUSY; /* remove us from our grantparent's channel list */ - err = pcm_chn_remove(d, c, !last); + err = pcm_chn_remove(d, c, !last || c->flags & CHN_F_NEWDEVICE); if (err) return err;