DF-4610 / fix.diff
diff --git a/sys/dev/sound/pci/neomagic.c b/sys/dev/sound/pci/neomagic.c index 6206653..5510614 100644 --- a/sys/dev/sound/pci/neomagic.c +++ b/sys/dev/sound/pci/neomagic.c @@ -690,10 +690,6 @@ nm_pci_attach(device_t dev) goto bad; } - codec = AC97_CREATE(dev, sc, nm_ac97); - if (codec == NULL) goto bad; - if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto bad; - sc->irqid = 0; sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid, RF_ACTIVE | RF_SHAREABLE); @@ -702,11 +698,24 @@ nm_pci_attach(device_t dev) goto bad; } + if (pcm_register(dev, sc, 1, 1)) goto bad; + + codec = AC97_CREATE(dev, sc, nm_ac97); + if (codec == NULL) goto bad; + if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) { + /* + * mixer_init() failed before the mixer cdev was + * published; destroy the codec here so bad: never + * frees an object a live /dev/mixerN still points at. + */ + ac97_destroy(codec); + codec = NULL; + goto bad; + } + ksnprintf(status, SND_STATUSLEN, "at memory 0x%lx, 0x%lx irq %ld %s", rman_get_start(sc->buf), rman_get_start(sc->reg), rman_get_start(sc->irq),PCM_KLDSTRING(snd_neomagic)); - - if (pcm_register(dev, sc, 1, 1)) goto bad; pcm_addchan(dev, PCMDIR_REC, &nmchan_class, sc); pcm_addchan(dev, PCMDIR_PLAY, &nmchan_class, sc); pcm_setstatus(dev, status); @@ -715,10 +724,10 @@ nm_pci_attach(device_t dev) bad: if (codec) ac97_destroy(codec); - if (sc->buf) bus_release_resource(dev, SYS_RES_MEMORY, sc->bufid, sc->buf); - if (sc->reg) bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg); if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih); if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); + if (sc->buf) bus_release_resource(dev, SYS_RES_MEMORY, sc->bufid, sc->buf); + if (sc->reg) bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg); kfree(sc, M_DEVBUF); return ENXIO; } |