Fix possible DMA leak and locking violation especially
during suspend <-> resume and module load <-> unload. PR: kern/92764 MFC after: 3 days
This commit is contained in:
parent
e3f1789aa0
commit
34733eb529
@ -677,7 +677,6 @@ static int
|
|||||||
ich_init(struct sc_info *sc)
|
ich_init(struct sc_info *sc)
|
||||||
{
|
{
|
||||||
u_int32_t stat;
|
u_int32_t stat;
|
||||||
int sz;
|
|
||||||
|
|
||||||
ich_wr(sc, ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD, 4);
|
ich_wr(sc, ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD, 4);
|
||||||
DELAY(600000);
|
DELAY(600000);
|
||||||
@ -701,15 +700,6 @@ ich_init(struct sc_info *sc)
|
|||||||
if (sc->hasmic && ich_resetchan(sc, 2))
|
if (sc->hasmic && ich_resetchan(sc, 2))
|
||||||
return ENXIO;
|
return ENXIO;
|
||||||
|
|
||||||
if (bus_dmamem_alloc(sc->dmat, (void **)&sc->dtbl, BUS_DMA_NOWAIT, &sc->dtmap))
|
|
||||||
return ENOSPC;
|
|
||||||
|
|
||||||
sz = sizeof(struct ich_desc) * ICH_DTBL_LENGTH * 3;
|
|
||||||
if (bus_dmamap_load(sc->dmat, sc->dtmap, sc->dtbl, sz, ich_setmap, sc, 0)) {
|
|
||||||
bus_dmamem_free(sc->dmat, (void **)&sc->dtbl, sc->dtmap);
|
|
||||||
return ENOSPC;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -828,6 +818,15 @@ ich_pci_attach(device_t dev)
|
|||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bus_dmamem_alloc(sc->dmat, (void **)&sc->dtbl,
|
||||||
|
BUS_DMA_NOWAIT, &sc->dtmap))
|
||||||
|
goto bad;
|
||||||
|
|
||||||
|
if (bus_dmamap_load(sc->dmat, sc->dtmap, sc->dtbl,
|
||||||
|
sizeof(struct ich_desc) * ICH_DTBL_LENGTH * 3,
|
||||||
|
ich_setmap, sc, 0))
|
||||||
|
goto bad;
|
||||||
|
|
||||||
sc->codec = AC97_CREATE(dev, sc, ich_ac97);
|
sc->codec = AC97_CREATE(dev, sc, ich_ac97);
|
||||||
if (sc->codec == NULL)
|
if (sc->codec == NULL)
|
||||||
goto bad;
|
goto bad;
|
||||||
@ -895,6 +894,10 @@ ich_pci_attach(device_t dev)
|
|||||||
if (sc->nabmbar)
|
if (sc->nabmbar)
|
||||||
bus_release_resource(dev, sc->regtype,
|
bus_release_resource(dev, sc->regtype,
|
||||||
sc->nabmbarid, sc->nabmbar);
|
sc->nabmbarid, sc->nabmbar);
|
||||||
|
if (sc->dtmap)
|
||||||
|
bus_dmamap_unload(sc->dmat, sc->dtmap);
|
||||||
|
if (sc->dmat)
|
||||||
|
bus_dma_tag_destroy(sc->dmat);
|
||||||
if (sc->ich_lock)
|
if (sc->ich_lock)
|
||||||
snd_mtxfree(sc->ich_lock);
|
snd_mtxfree(sc->ich_lock);
|
||||||
free(sc, M_DEVBUF);
|
free(sc, M_DEVBUF);
|
||||||
@ -916,6 +919,7 @@ ich_pci_detach(device_t dev)
|
|||||||
bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
|
bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
|
||||||
bus_release_resource(dev, sc->regtype, sc->nambarid, sc->nambar);
|
bus_release_resource(dev, sc->regtype, sc->nambarid, sc->nambar);
|
||||||
bus_release_resource(dev, sc->regtype, sc->nabmbarid, sc->nabmbar);
|
bus_release_resource(dev, sc->regtype, sc->nabmbarid, sc->nabmbar);
|
||||||
|
bus_dmamap_unload(sc->dmat, sc->dtmap);
|
||||||
bus_dma_tag_destroy(sc->dmat);
|
bus_dma_tag_destroy(sc->dmat);
|
||||||
snd_mtxfree(sc->ich_lock);
|
snd_mtxfree(sc->ich_lock);
|
||||||
free(sc, M_DEVBUF);
|
free(sc, M_DEVBUF);
|
||||||
@ -987,24 +991,21 @@ ich_pci_resume(device_t dev)
|
|||||||
}
|
}
|
||||||
/* Reinit mixer */
|
/* Reinit mixer */
|
||||||
ich_pci_codec_reset(sc);
|
ich_pci_codec_reset(sc);
|
||||||
|
ICH_UNLOCK(sc);
|
||||||
ac97_setextmode(sc->codec, sc->hasvra | sc->hasvrm);
|
ac97_setextmode(sc->codec, sc->hasvra | sc->hasvrm);
|
||||||
if (mixer_reinit(dev) == -1) {
|
if (mixer_reinit(dev) == -1) {
|
||||||
device_printf(dev, "unable to reinitialize the mixer\n");
|
device_printf(dev, "unable to reinitialize the mixer\n");
|
||||||
ICH_UNLOCK(sc);
|
|
||||||
return ENXIO;
|
return ENXIO;
|
||||||
}
|
}
|
||||||
/* Re-start DMA engines */
|
/* Re-start DMA engines */
|
||||||
for (i = 0 ; i < 3; i++) {
|
for (i = 0 ; i < 3; i++) {
|
||||||
struct sc_chinfo *ch = &sc->ch[i];
|
struct sc_chinfo *ch = &sc->ch[i];
|
||||||
if (sc->ch[i].run_save) {
|
if (sc->ch[i].run_save) {
|
||||||
ICH_UNLOCK(sc);
|
|
||||||
ichchan_setblocksize(0, ch, ch->blksz);
|
ichchan_setblocksize(0, ch, ch->blksz);
|
||||||
ichchan_setspeed(0, ch, ch->spd);
|
ichchan_setspeed(0, ch, ch->spd);
|
||||||
ichchan_trigger(0, ch, PCMTRIG_START);
|
ichchan_trigger(0, ch, PCMTRIG_START);
|
||||||
ICH_LOCK(sc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ICH_UNLOCK(sc);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user