diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c --- a/sys/dev/sound/pcm/channel.c +++ b/sys/dev/sound/pcm/channel.c @@ -1157,6 +1157,24 @@ return r; } +static struct unrhdr * +chn_getunr(int type) +{ + switch (type) { + case SND_DEV_DSPHW_PLAY: + return (p_unr); + case SND_DEV_DSPHW_VPLAY: + return (vp_unr); + case SND_DEV_DSPHW_REC: + return (r_unr); + case SND_DEV_DSPHW_VREC: + return (vr_unr); + default: + __assert_unreachable(); + } + +} + struct pcm_channel * chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, int dir, void *devinfo) @@ -1165,7 +1183,7 @@ struct feeder_class *fc; struct snd_dbuf *b, *bs; char *dirs, buf[CHN_NAMELEN]; - int i, direction, type, unit; + int i, direction, type; PCM_BUSYASSERT(d); PCM_LOCKASSERT(d); @@ -1198,13 +1216,6 @@ return (NULL); } - unit = 0; - CHN_FOREACH(c, d, channels.pcm) { - if (c->type != type) - continue; - unit++; - } - PCM_UNLOCK(d); b = NULL; bs = NULL; @@ -1216,7 +1227,7 @@ CHN_INIT(c, children.busy); c->direction = direction; c->type = type; - c->unit = unit; + c->unit = alloc_unr(chn_getunr(c->type)); c->format = SND_FORMAT(AFMT_U8, 1, 0); c->speed = DSP_DEFAULT_SPEED; c->pid = -1; @@ -1304,6 +1315,7 @@ return (c); fail: + free_unr(chn_getunr(c->type), c->unit); feeder_remove(c); if (c->devinfo && CHANNEL_FREE(c->methods, c->devinfo)) sndbuf_free(b); @@ -1335,6 +1347,7 @@ chn_trigger(c, PCMTRIG_ABORT); CHN_UNLOCK(c); } + free_unr(chn_getunr(c->type), c->unit); feeder_remove(c); if (CHANNEL_FREE(c->methods, c->devinfo)) sndbuf_free(b); diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h --- a/sys/dev/sound/pcm/sound.h +++ b/sys/dev/sound/pcm/sound.h @@ -242,6 +242,11 @@ extern int snd_verbose; extern devclass_t pcm_devclass; extern struct unrhdr *pcmsg_unrhdr; +extern struct unrhdr *p_unr; +extern struct unrhdr *vp_unr; +extern struct unrhdr *r_unr; +extern struct unrhdr *vr_unr; + #ifndef DEB #define DEB(x) diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c --- a/sys/dev/sound/pcm/sound.c +++ b/sys/dev/sound/pcm/sound.c @@ -65,6 +65,10 @@ * @brief Unit number allocator for syncgroup IDs */ struct unrhdr *pcmsg_unrhdr = NULL; +struct unrhdr *p_unr = NULL; +struct unrhdr *vp_unr = NULL; +struct unrhdr *r_unr = NULL; +struct unrhdr *vr_unr = NULL; void * snd_mtxcreate(const char *desc, const char *type) @@ -827,12 +831,32 @@ case MOD_LOAD: pcm_devclass = devclass_create("pcm"); pcmsg_unrhdr = new_unrhdr(1, INT_MAX, NULL); + p_unr = new_unrhdr(0, INT_MAX, NULL); + vp_unr = new_unrhdr(0, INT_MAX, NULL); + r_unr = new_unrhdr(0, INT_MAX, NULL); + vr_unr = new_unrhdr(0, INT_MAX, NULL); break; case MOD_UNLOAD: if (pcmsg_unrhdr != NULL) { delete_unrhdr(pcmsg_unrhdr); pcmsg_unrhdr = NULL; } + if (p_unr != NULL) { + delete_unrhdr(p_unr); + p_unr = NULL; + } + if (vp_unr != NULL) { + delete_unrhdr(vp_unr); + vp_unr = NULL; + } + if (r_unr != NULL) { + delete_unrhdr(r_unr); + r_unr = NULL; + } + if (vr_unr != NULL) { + delete_unrhdr(vr_unr); + vr_unr = NULL; + } break; case MOD_SHUTDOWN: break;