--- a/sys/dev/sound/pci/t4dwave.c +++ b/sys/dev/sound/pci/t4dwave.c @@ -830,7 +830,7 @@ struct tr_info *tr; struct ac97_info *codec = 0; bus_addr_t lowaddr; - int i, dacn; + int i, dacn, mixinit = 0; char status[SND_STATUSLEN]; tr = kmalloc(sizeof(*tr), M_DEVBUF, M_WAITOK | M_ZERO); @@ -880,6 +880,7 @@ codec = AC97_CREATE(dev, tr, tr_ac97); if (codec == NULL) goto bad; if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto bad; + mixinit = 1; tr->irqid = 0; tr->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &tr->irqid, @@ -935,7 +936,17 @@ return 0; bad: - if (codec) ac97_destroy(codec); + /* + * If mixer_init() succeeded, the 0666 /dev/mixerN cdev it created + * (mixer.c:730-733) still dispatches kobj methods through this + * codec. mixer_uninit() destroys the cdev, the snd_mixer and the + * codec itself (ac97mix_uninit -> ac97_destroy), mirroring the + * pcm_unregister() unwind order (sound.c:1205). + */ + if (mixinit) + mixer_uninit(dev); + else if (codec) + ac97_destroy(codec); if (tr->reg) bus_release_resource(dev, tr->regtype, tr->regid, tr->reg); if (tr->ih) bus_teardown_intr(dev, tr->irq, tr->ih); if (tr->irq) bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq);