detach support

remove un-needed setdir functions
add bus_teardown_intr calls where necessary
destroy our dma tags where necessary
destroy ac97 before releasing resources
This commit is contained in:
Cameron Grant 2000-09-09 19:21:04 +00:00
parent b47ce7f5cb
commit 306f91b60b
18 changed files with 436 additions and 189 deletions

View File

@ -49,6 +49,7 @@ struct ad1816_info {
int drq1_rid;
struct resource *drq2; /* rec */
int drq2_rid;
void *ih;
bus_dma_tag_t parent_dmat;
struct ad1816_chinfo pch, rch;
@ -480,6 +481,8 @@ static void
ad1816_release_resources(struct ad1816_info *ad1816, device_t dev)
{
if (ad1816->irq) {
if (ad1816->ih)
bus_teardown_intr(dev, ad1816->irq, ad1816->ih);
bus_release_resource(dev, SYS_RES_IRQ, ad1816->irq_rid,
ad1816->irq);
ad1816->irq = 0;
@ -499,7 +502,11 @@ ad1816_release_resources(struct ad1816_info *ad1816, device_t dev)
ad1816->io_base);
ad1816->io_base = 0;
}
free(ad1816, M_DEVBUF);
if (ad1816->parent_dmat) {
bus_dma_tag_destroy(ad1816->parent_dmat);
ad1816->parent_dmat = 0;
}
free(ad1816, M_DEVBUF);
}
static int
@ -575,7 +582,6 @@ static int
ad1816_attach(device_t dev)
{
struct ad1816_info *ad1816;
void *ih;
char status[SND_STATUSLEN];
ad1816 = (struct ad1816_info *)malloc(sizeof *ad1816, M_DEVBUF, M_NOWAIT);
@ -590,7 +596,7 @@ ad1816_attach(device_t dev)
if (!ad1816_alloc_resources(ad1816, dev)) goto no;
ad1816_init(ad1816, dev);
mixer_init(dev, &ad1816_mixer, ad1816);
bus_setup_intr(dev, ad1816->irq, INTR_TYPE_TTY, ad1816_intr, ad1816, &ih);
bus_setup_intr(dev, ad1816->irq, INTR_TYPE_TTY, ad1816_intr, ad1816, &ad1816->ih);
if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
/*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
/*highaddr*/BUS_SPACE_MAXADDR,
@ -621,10 +627,26 @@ ad1816_attach(device_t dev)
}
static int
ad1816_detach(device_t dev)
{
int r;
struct ad1816_info *ad1816;
r = pcm_unregister(dev);
if (r)
return r;
ad1816 = pcm_getdevinfo(dev);
ad1816_release_resources(ad1816, dev);
return 0;
}
static device_method_t ad1816_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ad1816_probe),
DEVMETHOD(device_attach, ad1816_attach),
DEVMETHOD(device_detach, ad1816_detach),
{ 0, 0 }
};

View File

@ -47,7 +47,6 @@
/* channel interface for ESS */
static void *esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir);
static int esschan_setdir(void *data, int dir);
static int esschan_setformat(void *data, u_int32_t format);
static int esschan_setspeed(void *data, u_int32_t speed);
static int esschan_setblocksize(void *data, u_int32_t blocksize);
@ -85,7 +84,7 @@ static pcmchan_caps ess_reccaps = {5000, 49000, ess_rfmt, 0};
static pcm_channel ess_chantemplate = {
esschan_init,
esschan_setdir,
NULL, /* setdir */
esschan_setformat,
esschan_setspeed,
esschan_setblocksize,
@ -117,6 +116,7 @@ struct ess_info {
struct resource *irq;
struct resource *drq1;
struct resource *drq2;
void *ih;
bus_dma_tag_t parent_dmat;
int type, duplex:1, newspeed:1;
@ -312,8 +312,9 @@ ess_reset_dsp(struct ess_info *sc)
static void
ess_release_resources(struct ess_info *sc, device_t dev)
{
/* should we bus_teardown_intr here? */
if (sc->irq) {
if (sc->ih)
bus_teardown_intr(dev, sc->irq, sc->ih);
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
sc->irq = 0;
}
@ -329,7 +330,11 @@ ess_release_resources(struct ess_info *sc, device_t dev)
bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->io_base);
sc->io_base = 0;
}
free(sc, M_DEVBUF);
if (sc->parent_dmat) {
bus_dma_tag_destroy(sc->parent_dmat);
sc->parent_dmat = 0;
}
free(sc, M_DEVBUF);
}
static int
@ -374,7 +379,6 @@ ess_alloc_resources(struct ess_info *sc, device_t dev)
static int
ess_doattach(device_t dev, struct ess_info *sc)
{
void *ih;
char status[SND_STATUSLEN], buf[64];
int ver;
@ -410,7 +414,7 @@ ess_doattach(device_t dev, struct ess_info *sc)
if (sc->newspeed)
ess_setmixer(sc, 0x71, 0x22);
bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, ess_intr, sc, &ih);
bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, ess_intr, sc, &sc->ih);
if (!sc->duplex)
pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX);
@ -445,6 +449,21 @@ ess_doattach(device_t dev, struct ess_info *sc)
return ENXIO;
}
static int
ess_detach(device_t dev)
{
int r;
struct ess_info *sc;
r = pcm_unregister(dev);
if (r)
return r;
sc = pcm_getdevinfo(dev);
ess_release_resources(sc, dev);
return 0;
}
static void
ess_intr(void *arg)
{
@ -650,6 +669,7 @@ esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
ch->buffer->bufsize = ESS_BUFFSIZE;
if (chn_allocbuf(ch->buffer, sc->parent_dmat) == -1)
return NULL;
ch->dir = dir;
ch->hwch = 1;
if ((dir == PCMDIR_PLAY) && (sc->duplex))
ch->hwch = 2;
@ -657,15 +677,6 @@ esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
return ch;
}
static int
esschan_setdir(void *data, int dir)
{
struct ess_chinfo *ch = data;
ch->dir = dir;
return 0;
}
static int
esschan_setformat(void *data, u_int32_t format)
{
@ -881,6 +892,7 @@ static device_method_t ess_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ess_probe),
DEVMETHOD(device_attach, ess_attach),
DEVMETHOD(device_detach, ess_detach),
{ 0, 0 }
};
@ -935,10 +947,17 @@ esscontrol_attach(device_t dev)
return 0;
}
static int
esscontrol_detach(device_t dev)
{
return 0;
}
static device_method_t esscontrol_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, esscontrol_probe),
DEVMETHOD(device_attach, esscontrol_attach),
DEVMETHOD(device_detach, esscontrol_detach),
{ 0, 0 }
};

View File

@ -60,6 +60,7 @@ struct mss_info {
int drq1_rid;
struct resource *drq2; /* rec */
int drq2_rid;
void *ih;
bus_dma_tag_t parent_dmat;
char mss_indexed_regs[MSS_INDEXED_REGS];
@ -284,7 +285,9 @@ static void
mss_release_resources(struct mss_info *mss, device_t dev)
{
if (mss->irq) {
bus_release_resource(dev, SYS_RES_IRQ, mss->irq_rid,
if (mss->ih)
bus_teardown_intr(dev, mss->irq, mss->ih);
bus_release_resource(dev, SYS_RES_IRQ, mss->irq_rid,
mss->irq);
mss->irq = 0;
}
@ -310,7 +313,11 @@ mss_release_resources(struct mss_info *mss, device_t dev)
mss->conf_base);
mss->conf_base = 0;
}
free(mss, M_DEVBUF);
if (mss->parent_dmat) {
bus_dma_tag_destroy(mss->parent_dmat);
mss->parent_dmat = 0;
}
free(mss, M_DEVBUF);
}
static int
@ -872,7 +879,6 @@ ymf_test(device_t dev, struct mss_info *mss)
static int
mss_doattach(device_t dev, struct mss_info *mss)
{
void *ih;
int flags = device_get_flags(dev);
char status[SND_STATUSLEN];
@ -914,10 +920,10 @@ mss_doattach(device_t dev, struct mss_info *mss)
mixer_init(dev, (mss->bd_id == MD_YM0020)? &yamaha_mixer : &mss_mixer, mss);
switch (mss->bd_id) {
case MD_OPTI931:
bus_setup_intr(dev, mss->irq, INTR_TYPE_TTY, opti931_intr, mss, &ih);
bus_setup_intr(dev, mss->irq, INTR_TYPE_TTY, opti931_intr, mss, &mss->ih);
break;
default:
bus_setup_intr(dev, mss->irq, INTR_TYPE_TTY, mss_intr, mss, &ih);
bus_setup_intr(dev, mss->irq, INTR_TYPE_TTY, mss_intr, mss, &mss->ih);
}
if (mss->pdma == mss->rdma)
pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX);
@ -947,6 +953,22 @@ mss_doattach(device_t dev, struct mss_info *mss)
return ENXIO;
}
static int
mss_detach(device_t dev)
{
int r;
struct mss_info *mss;
r = pcm_unregister(dev);
if (r)
return r;
mss = pcm_getdevinfo(dev);
mss_release_resources(mss, dev);
return 0;
}
static int
mss_attach(device_t dev)
{
@ -1043,6 +1065,7 @@ static device_method_t mss_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, mss_probe),
DEVMETHOD(device_attach, mss_attach),
DEVMETHOD(device_detach, mss_detach),
DEVMETHOD(device_suspend, mss_suspend),
DEVMETHOD(device_resume, mss_resume),
@ -1540,6 +1563,7 @@ static device_method_t pnpmss_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, pnpmss_probe),
DEVMETHOD(device_attach, pnpmss_attach),
DEVMETHOD(device_detach, mss_detach),
DEVMETHOD(device_suspend, mss_suspend),
DEVMETHOD(device_resume, mss_resume),
@ -1684,6 +1708,7 @@ guspcm_attach(device_t dev)
static device_method_t guspcm_methods[] = {
DEVMETHOD(device_probe, guspcm_probe),
DEVMETHOD(device_attach, guspcm_attach),
DEVMETHOD(device_detach, mss_detach),
{ 0, 0 }
};

View File

@ -132,6 +132,7 @@ struct sb_info {
struct resource *irq;
struct resource *drq1;
struct resource *drq2;
void *ih;
bus_dma_tag_t parent_dmat;
int bd_id;
@ -329,9 +330,10 @@ sb_reset_dsp(struct sb_info *sb)
static void
sb_release_resources(struct sb_info *sb, device_t dev)
{
/* should we bus_teardown_intr here? */
if (sb->irq) {
bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq);
if (sb->ih)
bus_teardown_intr(dev, sb->irq, sb->ih);
bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq);
sb->irq = 0;
}
if (sb->drq1) {
@ -346,7 +348,11 @@ sb_release_resources(struct sb_info *sb, device_t dev)
bus_release_resource(dev, SYS_RES_IOPORT, 0, sb->io_base);
sb->io_base = 0;
}
free(sb, M_DEVBUF);
if (sb->parent_dmat) {
bus_dma_tag_destroy(sb->parent_dmat);
sb->parent_dmat = 0;
}
free(sb, M_DEVBUF);
}
static int
@ -421,7 +427,6 @@ sb16_swap(void *v, int dir)
static int
sb_doattach(device_t dev, struct sb_info *sb)
{
void *ih;
char status[SND_STATUSLEN];
int bs = DSP_BUFFSIZE;
@ -431,7 +436,7 @@ sb_doattach(device_t dev, struct sb_info *sb)
goto no;
mixer_init(dev, &sb_mixer, sb);
bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih);
bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &sb->ih);
if ((sb->bd_flags & BD_F_SB16) && !(sb->bd_flags & BD_F_SB16X))
pcm_setswap(dev, sb16_swap);
if (!sb->drq2)
@ -468,6 +473,21 @@ sb_doattach(device_t dev, struct sb_info *sb)
return ENXIO;
}
static int
sb_detach(device_t dev)
{
int r;
struct sb_info *sb;
r = pcm_unregister(dev);
if (r)
return r;
sb = pcm_getdevinfo(dev);
sb_release_resources(sb, dev);
return 0;
}
static void
sb_intr(void *arg)
{
@ -897,6 +917,7 @@ static device_method_t sbsbc_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, sbsbc_probe),
DEVMETHOD(device_attach, sbsbc_attach),
DEVMETHOD(device_detach, sb_detach),
{ 0, 0 }
};

View File

@ -132,6 +132,7 @@ struct sb_info {
struct resource *irq;
struct resource *drq1;
struct resource *drq2;
void *ih;
bus_dma_tag_t parent_dmat;
int bd_id;
@ -329,9 +330,10 @@ sb_reset_dsp(struct sb_info *sb)
static void
sb_release_resources(struct sb_info *sb, device_t dev)
{
/* should we bus_teardown_intr here? */
if (sb->irq) {
bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq);
if (sb->ih)
bus_teardown_intr(dev, sb->irq, sb->ih);
bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq);
sb->irq = 0;
}
if (sb->drq1) {
@ -346,7 +348,11 @@ sb_release_resources(struct sb_info *sb, device_t dev)
bus_release_resource(dev, SYS_RES_IOPORT, 0, sb->io_base);
sb->io_base = 0;
}
free(sb, M_DEVBUF);
if (sb->parent_dmat) {
bus_dma_tag_destroy(sb->parent_dmat);
sb->parent_dmat = 0;
}
free(sb, M_DEVBUF);
}
static int
@ -421,7 +427,6 @@ sb16_swap(void *v, int dir)
static int
sb_doattach(device_t dev, struct sb_info *sb)
{
void *ih;
char status[SND_STATUSLEN];
int bs = DSP_BUFFSIZE;
@ -431,7 +436,7 @@ sb_doattach(device_t dev, struct sb_info *sb)
goto no;
mixer_init(dev, &sb_mixer, sb);
bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih);
bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &sb->ih);
if ((sb->bd_flags & BD_F_SB16) && !(sb->bd_flags & BD_F_SB16X))
pcm_setswap(dev, sb16_swap);
if (!sb->drq2)
@ -468,6 +473,21 @@ sb_doattach(device_t dev, struct sb_info *sb)
return ENXIO;
}
static int
sb_detach(device_t dev)
{
int r;
struct sb_info *sb;
r = pcm_unregister(dev);
if (r)
return r;
sb = pcm_getdevinfo(dev);
sb_release_resources(sb, dev);
return 0;
}
static void
sb_intr(void *arg)
{
@ -897,6 +917,7 @@ static device_method_t sbsbc_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, sbsbc_probe),
DEVMETHOD(device_attach, sbsbc_attach),
DEVMETHOD(device_detach, sb_detach),
{ 0, 0 }
};

View File

@ -132,6 +132,7 @@ struct sb_info {
struct resource *irq;
struct resource *drq1;
struct resource *drq2;
void *ih;
bus_dma_tag_t parent_dmat;
int bd_id;
@ -329,9 +330,10 @@ sb_reset_dsp(struct sb_info *sb)
static void
sb_release_resources(struct sb_info *sb, device_t dev)
{
/* should we bus_teardown_intr here? */
if (sb->irq) {
bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq);
if (sb->ih)
bus_teardown_intr(dev, sb->irq, sb->ih);
bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq);
sb->irq = 0;
}
if (sb->drq1) {
@ -346,7 +348,11 @@ sb_release_resources(struct sb_info *sb, device_t dev)
bus_release_resource(dev, SYS_RES_IOPORT, 0, sb->io_base);
sb->io_base = 0;
}
free(sb, M_DEVBUF);
if (sb->parent_dmat) {
bus_dma_tag_destroy(sb->parent_dmat);
sb->parent_dmat = 0;
}
free(sb, M_DEVBUF);
}
static int
@ -421,7 +427,6 @@ sb16_swap(void *v, int dir)
static int
sb_doattach(device_t dev, struct sb_info *sb)
{
void *ih;
char status[SND_STATUSLEN];
int bs = DSP_BUFFSIZE;
@ -431,7 +436,7 @@ sb_doattach(device_t dev, struct sb_info *sb)
goto no;
mixer_init(dev, &sb_mixer, sb);
bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih);
bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &sb->ih);
if ((sb->bd_flags & BD_F_SB16) && !(sb->bd_flags & BD_F_SB16X))
pcm_setswap(dev, sb16_swap);
if (!sb->drq2)
@ -468,6 +473,21 @@ sb_doattach(device_t dev, struct sb_info *sb)
return ENXIO;
}
static int
sb_detach(device_t dev)
{
int r;
struct sb_info *sb;
r = pcm_unregister(dev);
if (r)
return r;
sb = pcm_getdevinfo(dev);
sb_release_resources(sb, dev);
return 0;
}
static void
sb_intr(void *arg)
{
@ -897,6 +917,7 @@ static device_method_t sbsbc_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, sbsbc_probe),
DEVMETHOD(device_attach, sbsbc_attach),
DEVMETHOD(device_detach, sb_detach),
{ 0, 0 }
};

View File

@ -58,7 +58,7 @@ struct sbc_softc {
struct sbc_ihl ihl[IRQ_MAX];
void *ih;
void *ih[IRQ_MAX];
u_int32_t bd_ver;
};
@ -372,9 +372,11 @@ sbc_attach(device_t dev)
else sb_setmixer(scp->io[0], IRQ_NR, x);
sb_setmixer(scp->io[0], DMA_NR, (1 << dh) | (1 << dl));
#endif
device_printf(dev, "setting card to irq %d, drq %d", irq, dl);
if (dl != dh) printf(", %d", dh);
printf("\n");
if (bootverbose) {
device_printf(dev, "setting card to irq %d, drq %d", irq, dl);
if (dl != dh) printf(", %d", dh);
printf("\n");
}
break;
}
@ -389,7 +391,7 @@ sbc_attach(device_t dev)
err = "setup_intr";
for (i = 0; i < IRQ_MAX; i++) {
if (bus_setup_intr(dev, scp->irq[i], INTR_TYPE_TTY, sbc_intr, &scp->ihl[i], &scp->ih))
if (bus_setup_intr(dev, scp->irq[i], INTR_TYPE_TTY, sbc_intr, &scp->ihl[i], &scp->ih[i]))
goto bad;
}
@ -427,6 +429,15 @@ bad: if (err) device_printf(dev, "%s\n", err);
return (ENXIO);
}
static int
sbc_detach(device_t dev)
{
struct sbc_softc *scp = device_get_softc(dev);
release_resource(scp);
return bus_generic_detach(dev);
}
static void
sbc_intr(void *p)
{
@ -648,7 +659,7 @@ alloc_resource(struct sbc_softc *scp)
}
}
for (i = 0 ; i < IRQ_MAX ; i++) {
if (scp->irq[i] == NULL) {
if (scp->irq[i] == NULL) {
scp->irq_rid[i] = i;
scp->irq[i] = bus_alloc_resource(scp->dev, SYS_RES_IRQ, &scp->irq_rid[i],
0, ~0, 1, RF_ACTIVE);
@ -679,6 +690,9 @@ release_resource(struct sbc_softc *scp)
}
for (i = 0 ; i < IRQ_MAX ; i++) {
if (scp->irq[i] != NULL) {
if (scp->ih[i] != NULL)
bus_teardown_intr(scp->dev, scp->irq[i], scp->ih[i]);
scp->ih[i] = NULL;
bus_release_resource(scp->dev, SYS_RES_IRQ, scp->irq_rid[i], scp->irq[i]);
scp->irq[i] = NULL;
}
@ -690,7 +704,7 @@ static device_method_t sbc_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, sbc_probe),
DEVMETHOD(device_attach, sbc_attach),
DEVMETHOD(device_detach, bus_generic_detach),
DEVMETHOD(device_detach, sbc_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),

View File

@ -751,6 +751,8 @@ csa_releaseres(struct csa_info *csa, device_t dev)
resp = &csa->res;
if (resp->irq != NULL) {
if (csa->ih)
bus_teardown_intr(dev, resp->irq, csa->ih);
bus_release_resource(dev, SYS_RES_IRQ, resp->irq_rid, resp->irq);
resp->irq = NULL;
}
@ -762,6 +764,14 @@ csa_releaseres(struct csa_info *csa, device_t dev)
bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem);
resp->mem = NULL;
}
if (csa->parent_dmat != NULL) {
bus_dma_tag_destroy(csa->parent_dmat);
csa->parent_dmat = NULL;
}
if (csa != NULL) {
free(csa, M_DEVBUF);
csa = NULL;
}
}
static int pcmcsa_probe(device_t dev);
@ -824,15 +834,21 @@ pcmcsa_attach(device_t dev)
return (ENXIO);
}
codec = ac97_create(dev, csa, NULL, csa_rdcd, csa_wrcd);
if (codec == NULL)
if (codec == NULL) {
csa_releaseres(csa, dev);
return (ENXIO);
if (mixer_init(dev, &ac97_mixer, codec) == -1)
}
if (mixer_init(dev, &ac97_mixer, codec) == -1) {
ac97_destroy(codec);
csa_releaseres(csa, dev);
return (ENXIO);
}
snprintf(status, SND_STATUSLEN, "at irq %ld", rman_get_start(resp->irq));
/* Enable interrupt. */
if (bus_setup_intr(dev, resp->irq, INTR_TYPE_TTY, csa_intr, csa, &csa->ih)) {
ac97_destroy(codec);
csa_releaseres(csa, dev);
return (ENXIO);
}
@ -840,6 +856,7 @@ pcmcsa_attach(device_t dev)
csa_writemem(resp, BA1_CIE, (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001);
if (pcm_register(dev, csa, 1, 1)) {
ac97_destroy(codec);
csa_releaseres(csa, dev);
return (ENXIO);
}
@ -850,6 +867,22 @@ pcmcsa_attach(device_t dev)
return (0);
}
static int
pcmcsa_detach(device_t dev)
{
int r;
struct csa_info *csa;
r = pcm_unregister(dev);
if (r)
return r;
csa = pcm_getdevinfo(dev);
csa_releaseres(csa, dev);
return 0;
}
/* ac97 codec */
static u_int32_t
@ -876,6 +909,7 @@ static device_method_t pcmcsa_methods[] = {
/* Device interface */
DEVMETHOD(device_probe , pcmcsa_probe ),
DEVMETHOD(device_attach, pcmcsa_attach),
DEVMETHOD(device_detach, pcmcsa_detach),
{ 0, 0 },
};

View File

@ -210,7 +210,7 @@ static pcmchan_caps ds_playcaps = {4000, 96000, ds_playfmt, 0};
static pcm_channel ds_pchantemplate = {
ds1pchan_init,
ds1pchan_setdir,
NULL, /* setdir */
ds1pchan_setformat,
ds1pchan_setspeed,
ds1pchan_setblocksize,
@ -229,7 +229,7 @@ static pcm_channel ds_pchantemplate = {
static pcm_channel ds_rchantemplate = {
ds1rchan_init,
ds1rchan_setdir,
NULL, /* setdir */
ds1rchan_setformat,
ds1rchan_setspeed,
ds1rchan_setblocksize,
@ -549,12 +549,6 @@ ds1pchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
}
}
static int
ds1pchan_setdir(void *data, int dir)
{
return 0;
}
static int
ds1pchan_setformat(void *data, u_int32_t format)
{
@ -660,12 +654,6 @@ ds1rchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
}
}
static int
ds1rchan_setdir(void *data, int dir)
{
return 0;
}
static int
ds1rchan_setformat(void *data, u_int32_t format)
{
@ -938,7 +926,7 @@ ds_pci_attach(device_t dev)
u_int32_t data;
u_int32_t subdev, i;
struct sc_info *sc;
struct ac97_info *codec;
struct ac97_info *codec = NULL;
char status[SND_STATUSLEN];
if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) {
@ -1012,12 +1000,16 @@ ds_pci_attach(device_t dev)
return 0;
bad:
if (codec)
ac97_destroy(codec);
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->parent_dmat)
bus_dma_tag_destroy(sc->parent_dmat);
free(sc, M_DEVBUF);
return ENXIO;
}
@ -1052,12 +1044,10 @@ ds_pci_detach(device_t dev)
sc = pcm_getdevinfo(dev);
ds_uninit(sc);
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);
bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg);
bus_teardown_intr(dev, sc->irq, sc->ih);
bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
bus_dma_tag_destroy(sc->parent_dmat);
free(sc, M_DEVBUF);
return 0;
}

View File

@ -1410,7 +1410,7 @@ emu_pci_attach(device_t dev)
{
u_int32_t data;
struct sc_info *sc;
struct ac97_info *codec;
struct ac97_info *codec = NULL;
int i, mapped;
char status[SND_STATUSLEN];
@ -1496,9 +1496,11 @@ emu_pci_attach(device_t dev)
return 0;
bad:
if (codec) ac97_destroy(codec);
if (sc->reg) bus_release_resource(dev, sc->regtype, 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->parent_dmat) bus_dma_tag_destroy(sc->parent_dmat);
free(sc, M_DEVBUF);
return ENXIO;
}
@ -1520,6 +1522,7 @@ emu_pci_detach(device_t dev)
bus_release_resource(dev, sc->regtype, sc->regid, sc->reg);
bus_teardown_intr(dev, sc->irq, sc->ih);
bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
bus_dma_tag_destroy(sc->parent_dmat);
free(sc, M_DEVBUF);
return 0;

View File

@ -88,6 +88,10 @@ struct es_info {
bus_space_handle_t sh;
bus_dma_tag_t parent_dmat;
struct resource *reg, *irq;
int regtype, regid, irqid;
void *ih;
device_t dev;
int num;
/* Contents of board's registers */
@ -761,15 +765,9 @@ es_pci_attach(device_t dev)
{
u_int32_t data;
struct es_info *es = 0;
int type = 0;
int regid;
struct resource *reg = 0;
int mapped;
int irqid;
struct resource *irq = 0;
void *ih = 0;
char status[SND_STATUSLEN];
struct ac97_info *codec;
struct ac97_info *codec = 0;
pcm_channel *ct = NULL;
if ((es = malloc(sizeof *es, M_DEVBUF, M_NOWAIT)) == NULL) {
@ -785,24 +783,24 @@ es_pci_attach(device_t dev)
pci_write_config(dev, PCIR_COMMAND, data, 2);
data = pci_read_config(dev, PCIR_COMMAND, 2);
if (mapped == 0 && (data & PCIM_CMD_MEMEN)) {
regid = MEM_MAP_REG;
type = SYS_RES_MEMORY;
reg = bus_alloc_resource(dev, type, &regid,
es->regid = MEM_MAP_REG;
es->regtype = SYS_RES_MEMORY;
es->reg = bus_alloc_resource(dev, es->regtype, &es->regid,
0, ~0, 1, RF_ACTIVE);
if (reg) {
es->st = rman_get_bustag(reg);
es->sh = rman_get_bushandle(reg);
if (es->reg) {
es->st = rman_get_bustag(es->reg);
es->sh = rman_get_bushandle(es->reg);
mapped++;
}
}
if (mapped == 0 && (data & PCIM_CMD_PORTEN)) {
regid = PCIR_MAPS;
type = SYS_RES_IOPORT;
reg = bus_alloc_resource(dev, type, &regid,
es->regid = PCIR_MAPS;
es->regtype = SYS_RES_IOPORT;
es->reg = bus_alloc_resource(dev, es->regtype, &es->regid,
0, ~0, 1, RF_ACTIVE);
if (reg) {
es->st = rman_get_bustag(reg);
es->sh = rman_get_bushandle(reg);
if (es->reg) {
es->st = rman_get_bustag(es->reg);
es->sh = rman_get_bushandle(es->reg);
mapped++;
}
}
@ -834,11 +832,11 @@ es_pci_attach(device_t dev)
ct = &es1370_chantemplate;
} else goto bad;
irqid = 0;
irq = bus_alloc_resource(dev, SYS_RES_IRQ, &irqid,
es->irqid = 0;
es->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &es->irqid,
0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
if (!irq
|| bus_setup_intr(dev, irq, INTR_TYPE_TTY, es_intr, es, &ih)) {
if (!es->irq
|| bus_setup_intr(dev, es->irq, INTR_TYPE_TTY, es_intr, es, &es->ih)) {
device_printf(dev, "unable to map interrupt\n");
goto bad;
}
@ -854,8 +852,8 @@ es_pci_attach(device_t dev)
}
snprintf(status, SND_STATUSLEN, "at %s 0x%lx irq %ld",
(type == SYS_RES_IOPORT)? "io" : "memory",
rman_get_start(reg), rman_get_start(irq));
(es->regtype == SYS_RES_IOPORT)? "io" : "memory",
rman_get_start(es->reg), rman_get_start(es->irq));
if (pcm_register(dev, es, 1, 1)) goto bad;
pcm_addchan(dev, PCMDIR_REC, ct, es);
@ -865,17 +863,40 @@ es_pci_attach(device_t dev)
return 0;
bad:
if (codec) ac97_destroy(codec);
if (es->reg) bus_release_resource(dev, es->regtype, es->regid, es->reg);
if (es->ih) bus_teardown_intr(dev, es->irq, es->ih);
if (es->irq) bus_release_resource(dev, SYS_RES_IRQ, es->irqid, es->irq);
if (es->parent_dmat) bus_dma_tag_destroy(es->parent_dmat);
if (es) free(es, M_DEVBUF);
if (reg) bus_release_resource(dev, type, regid, reg);
if (ih) bus_teardown_intr(dev, irq, ih);
if (irq) bus_release_resource(dev, SYS_RES_IRQ, irqid, irq);
return ENXIO;
}
static int
es_pci_detach(device_t dev)
{
int r;
struct es_info *es;
r = pcm_unregister(dev);
if (r)
return r;
es = pcm_getdevinfo(dev);
bus_release_resource(dev, es->regtype, es->regid, es->reg);
bus_teardown_intr(dev, es->irq, es->ih);
bus_release_resource(dev, SYS_RES_IRQ, es->irqid, es->irq);
bus_dma_tag_destroy(es->parent_dmat);
free(es, M_DEVBUF);
return 0;
}
static device_method_t es_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, es_pci_probe),
DEVMETHOD(device_attach, es_pci_attach),
DEVMETHOD(device_detach, es_pci_detach),
{ 0, 0 }
};

View File

@ -104,7 +104,6 @@
/* channel interface */
static void *fm801ch_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir);
static int fm801ch_setdir(void *data, int dir);
static int fm801ch_setformat(void *data, u_int32_t format);
static int fm801ch_setspeed(void *data, u_int32_t speed);
static int fm801ch_setblocksize(void *data, u_int32_t blocksize);
@ -119,9 +118,7 @@ static u_int32_t fmts[] = {
AFMT_U8,
AFMT_STEREO | AFMT_U8,
AFMT_S16_LE,
AFMT_STEREO | AFMT_S16_LE, /*
AFMT_STEREO | (AFMT_S16_LE | AFMT_S16_BE | AFMT_U16_LE | AFMT_U16_BE),
(AFMT_S16_LE | AFMT_S16_BE | AFMT_U16_LE | AFMT_U16_BE), */
AFMT_STEREO | AFMT_S16_LE,
0
};
@ -132,7 +129,7 @@ static pcmchan_caps fm801ch_caps = {
static pcm_channel fm801_chantemplate = {
fm801ch_init,
fm801ch_setdir,
NULL, /* setdir */
fm801ch_setformat,
fm801ch_setspeed,
fm801ch_setblocksize,
@ -192,23 +189,6 @@ struct fm801_info {
struct fm801_chinfo pch, rch;
};
/* several procedures to release the thing properly if compiled as module */
static struct fm801_info *save801;
struct fm801_info *fm801_get __P((void ));
static void
fm801_save(struct fm801_info *fm801)
{
save801 = fm801;
}
struct fm801_info *
fm801_get(void )
{
return save801;
}
/* Bus Read / Write routines */
static u_int32_t
fm801_rd(struct fm801_info *fm801, int regno, int size)
@ -395,7 +375,7 @@ static int
fm801_pci_attach(device_t dev)
{
u_int32_t data;
struct ac97_info *codec;
struct ac97_info *codec = 0;
struct fm801_info *fm801;
int i;
int mapped = 0;
@ -475,18 +455,39 @@ fm801_pci_attach(device_t dev)
pcm_addchan(dev, PCMDIR_REC, &fm801_chantemplate, fm801);
pcm_setstatus(dev, status);
fm801_save(fm801);
return 0;
oops:
printf("Forte Media FM801 initialization failed\n");
if (codec) ac97_destroy(codec);
if (fm801->reg) bus_release_resource(dev, fm801->regtype, fm801->regid, fm801->reg);
if (fm801->ih) bus_teardown_intr(dev, fm801->irq, fm801->ih);
if (fm801->irq) bus_release_resource(dev, SYS_RES_IRQ, fm801->irqid, fm801->irq);
if (fm801->parent_dmat) bus_dma_tag_destroy(fm801->parent_dmat);
free(fm801, M_DEVBUF);
return ENXIO;
}
static int
fm801_pci_detach(device_t dev)
{
int r;
struct fm801_info *fm801;
DPRINT("Forte Media FM801 detach\n");
r = pcm_unregister(dev);
if (r)
return r;
fm801 = pcm_getdevinfo(dev);
bus_release_resource(dev, fm801->regtype, fm801->regid, fm801->reg);
bus_teardown_intr(dev, fm801->irq, fm801->ih);
bus_release_resource(dev, SYS_RES_IRQ, fm801->irqid, fm801->irq);
bus_dma_tag_destroy(fm801->parent_dmat);
free(fm801, M_DEVBUF);
return 0;
}
static int
fm801_pci_probe( device_t dev )
{
@ -523,14 +524,6 @@ fm801ch_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
return (void *)ch;
}
static int
fm801ch_setdir(void *data, int dir)
{
struct fm801_chinfo *ch = data;
ch->dir = dir;
return 0;
}
static int
fm801ch_setformat(void *data, u_int32_t format)
{
@ -716,20 +709,6 @@ fm801ch_getcaps(void *data)
return &fm801ch_caps;
}
static int
fm801_pci_detach(device_t dev)
{
struct fm801_info *fm801 = fm801_get();
DPRINT("Forte Media FM801 detach\n");
if (fm801->reg) bus_release_resource(dev, fm801->regtype, fm801->regid, fm801->reg);
if (fm801->ih) bus_teardown_intr(dev, fm801->irq, fm801->ih);
if (fm801->irq) bus_release_resource(dev, SYS_RES_IRQ, fm801->irqid, fm801->irq);
free(fm801, M_DEVBUF);
return 0;
}
static device_method_t fm801_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, fm801_pci_probe),
@ -746,4 +725,4 @@ static driver_t fm801_driver = {
static devclass_t pcm_devclass;
DRIVER_MODULE(fm801, pci, fm801_driver, pcm_devclass,0, 0);
DRIVER_MODULE(fm801, pci, fm801_driver, pcm_devclass, 0, 0);

View File

@ -1041,12 +1041,12 @@ agg_attach(device_t dev)
return 0;
bad:
if (codec != NULL)
ac97_destroy(codec);
if (ih != NULL)
bus_teardown_intr(dev, irq, ih);
if (irq != NULL)
bus_release_resource(dev, SYS_RES_IRQ, irqid, irq);
if (codec != NULL)
free(codec, M_DEVBUF);
if (reg != NULL)
bus_release_resource(dev, SYS_RES_IOPORT, regid, reg);
if (ess != NULL) {

View File

@ -137,7 +137,7 @@ static pcmchan_caps nm_caps = {4000, 48000, nm_fmt, 0};
static pcm_channel nm_chantemplate = {
nmchan_init,
nmchan_setdir,
NULL, /* setdir */
nmchan_setformat,
nmchan_setspeed,
nmchan_setblocksize,
@ -378,12 +378,6 @@ nmchan_free(void *data)
return 0;
}
static int
nmchan_setdir(void *data, int dir)
{
return 0;
}
static int
nmchan_setformat(void *data, u_int32_t format)
{
@ -599,7 +593,7 @@ nm_pci_attach(device_t dev)
{
u_int32_t data;
struct sc_info *sc;
struct ac97_info *codec;
struct ac97_info *codec = 0;
char status[SND_STATUSLEN];
if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) {
@ -658,6 +652,7 @@ nm_pci_attach(device_t dev)
return 0;
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);
@ -666,6 +661,26 @@ nm_pci_attach(device_t dev)
return ENXIO;
}
static int
nm_pci_detach(device_t dev)
{
int r;
struct sc_info *sc;
r = pcm_unregister(dev);
if (r)
return r;
sc = pcm_getdevinfo(dev);
bus_release_resource(dev, SYS_RES_MEMORY, sc->bufid, sc->buf);
bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg);
bus_teardown_intr(dev, sc->irq, sc->ih);
bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
free(sc, M_DEVBUF);
return 0;
}
static int
nm_pci_resume(device_t dev)
{

View File

@ -83,7 +83,7 @@ static pcmchan_caps ess_reccaps = {5000, 49000, ess_recfmt, 0};
static pcm_channel ess_chantemplate = {
esschan_init,
esschan_setdir,
NULL, /* setdir */
esschan_setformat,
esschan_setspeed,
esschan_setblocksize,
@ -113,6 +113,7 @@ struct ess_chinfo {
struct ess_info {
struct resource *io, *sb, *vc, *mpu, *gp; /* I/O address for the board */
struct resource *irq;
void *ih;
bus_dma_tag_t parent_dmat;
int simplex_dir, type, duplex:1, newspeed:1, dmasz[2];
@ -557,6 +558,7 @@ esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
ch->channel = c;
ch->buffer = b;
ch->buffer->bufsize = ESS_BUFFSIZE;
ch->dir = dir;
if (chn_allocbuf(ch->buffer, sc->parent_dmat) == -1)
return NULL;
ch->hwch = 1;
@ -565,15 +567,6 @@ esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
return ch;
}
static int
esschan_setdir(void *data, int dir)
{
struct ess_chinfo *ch = data;
ch->dir = dir;
return 0;
}
static int
esschan_setformat(void *data, u_int32_t format)
{
@ -830,6 +823,8 @@ ess_release_resources(struct ess_info *sc, device_t dev)
{
/* should we bus_teardown_intr here? */
if (sc->irq) {
if (sc->ih)
bus_teardown_intr(dev, sc->irq, sc->ih);
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
sc->irq = 0;
}
@ -858,6 +853,11 @@ ess_release_resources(struct ess_info *sc, device_t dev)
sc->gp = 0;
}
if (sc->parent_dmat) {
bus_dma_tag_destroy(sc->parent_dmat);
sc->parent_dmat = 0;
}
free(sc, M_DEVBUF);
}
@ -918,7 +918,6 @@ static int
ess_attach(device_t dev)
{
struct ess_info *sc;
void *ih;
char status[SND_STATUSLEN];
u_int16_t ddma;
u_int32_t data;
@ -960,7 +959,7 @@ ess_attach(device_t dev)
if (sc->newspeed)
ess_setmixer(sc, 0x71, 0x2a);
bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, ess_intr, sc, &ih);
bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, ess_intr, sc, &sc->ih);
if (!sc->duplex)
pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX);
@ -992,10 +991,26 @@ ess_attach(device_t dev)
return ENXIO;
}
static int
ess_detach(device_t dev)
{
int r;
struct sc_info *sc;
r = pcm_unregister(dev);
if (r)
return r;
sc = pcm_getdevinfo(dev);
ess_release_resources(sc, dev);
return 0;
}
static device_method_t ess_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ess_probe),
DEVMETHOD(device_attach, ess_attach),
DEVMETHOD(device_detach, ess_detach),
{ 0, 0 }
};

View File

@ -695,17 +695,40 @@ tr_pci_attach(device_t dev)
return 0;
bad:
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);
if (tr->parent_dmat) bus_dma_tag_destroy(tr->parent_dmat);
free(tr, M_DEVBUF);
return ENXIO;
}
static int
tr_pci_detach(device_t dev)
{
int r;
struct tr_info *tr;
r = pcm_unregister(dev);
if (r)
return r;
tr = pcm_getdevinfo(dev);
bus_release_resource(dev, tr->regtype, tr->regid, tr->reg);
bus_teardown_intr(dev, tr->irq, tr->ih);
bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq);
bus_dma_tag_destroy(tr->parent_dmat);
free(tr, M_DEVBUF);
return 0;
}
static device_method_t tr_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, tr_pci_probe),
DEVMETHOD(device_attach, tr_pci_attach),
DEVMETHOD(device_detach, tr_pci_detach),
{ 0, 0 }
};

View File

@ -58,6 +58,10 @@ struct via_info {
bus_dma_tag_t parent_dmat;
bus_dma_tag_t sgd_dmat;
struct resource *reg, *irq;
int regid, irqid;
void *ih;
struct via_chinfo pch, rch;
struct via_dma_op *sgd_table;
u_int16_t codec_caps;
@ -146,15 +150,10 @@ static int
via_attach(device_t dev)
{
struct via_info *via = 0;
struct ac97_info *codec;
struct ac97_info *codec = 0;
char status[SND_STATUSLEN];
u_int32_t data;
struct resource *reg = 0;
int regid;
struct resource *irq = 0;
void *ih = 0;
int irqid;
u_int16_t v;
bus_dmamap_t sgd_dma_map;
@ -175,21 +174,21 @@ via_attach(device_t dev)
VIA_PCICONF_ACLINKENAB | VIA_PCICONF_ACSGD |
VIA_PCICONF_ACNOTRST | VIA_PCICONF_ACVSR, 1);
regid = PCIR_MAPS;
reg = bus_alloc_resource(dev, SYS_RES_IOPORT, &regid,
via->regid = PCIR_MAPS;
via->reg = bus_alloc_resource(dev, SYS_RES_IOPORT, &via->regid,
0, ~0, 1, RF_ACTIVE);
if (!reg) {
if (!via->reg) {
device_printf(dev, "via: Cannot allocate bus resource.");
goto bad;
}
via->st = rman_get_bustag(reg);
via->sh = rman_get_bushandle(reg);
via->st = rman_get_bustag(via->reg);
via->sh = rman_get_bushandle(via->reg);
irqid = 0;
irq = bus_alloc_resource(dev, SYS_RES_IRQ, &irqid,
via->irqid = 0;
via->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &via->irqid,
0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
if (!irq
|| bus_setup_intr(dev, irq, INTR_TYPE_TTY, via_intr, via, &ih)){
if (!via->irq
|| bus_setup_intr(dev, via->irq, INTR_TYPE_TTY, via_intr, via, &via->ih)){
device_printf(dev, "unable to map interrupt\n");
goto bad;
}
@ -216,8 +215,8 @@ via_attach(device_t dev)
via_write_codec(via, AC97_REG_EXT_AUDIO_STAT, v);
via->codec_caps = v;
{
v = via_read_codec(via, AC97_REG_EXT_AUDIO_STAT);
DEB(printf("init: codec stat: %d\n", v));
v = via_read_codec(via, AC97_REG_EXT_AUDIO_STAT);
DEB(printf("init: codec stat: %d\n", v));
}
if (!(v & AC97_CODEC_DOES_VRA)) {
@ -259,7 +258,7 @@ via_attach(device_t dev)
NSEGS * sizeof(struct via_dma_op), dma_cb, 0, 0)) goto bad;
snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld",
rman_get_start(reg), rman_get_start(irq));
rman_get_start(via->reg), rman_get_start(via->irq));
/* Register */
if (pcm_register(dev, via, 1, 1)) goto bad;
@ -268,17 +267,41 @@ via_attach(device_t dev)
pcm_setstatus(dev, status);
return 0;
bad:
if (codec) ac97_destroy(codec);
if (via->reg) bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg);
if (via->ih) bus_teardown_intr(dev, via->irq, via->ih);
if (via->irq) bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq);
if (via->parent_dmat) bus_dma_tag_destroy(via->parent_dmat);
if (via->sgd_dmat) bus_dma_tag_destroy(via->sgd_dmat);
if (via) free(via, M_DEVBUF);
bus_release_resource(dev, SYS_RES_IOPORT, regid, reg);
if (ih) bus_teardown_intr(dev, irq, ih);
if (irq) bus_release_resource(dev, SYS_RES_IRQ, irqid, irq);
return ENXIO;
}
static int
via_detach(device_t dev)
{
int r;
struct via_info *via = 0;
r = pcm_unregister(dev);
if (r)
return r;
via = pcm_getdevinfo(dev);
bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg);
bus_teardown_intr(dev, via->irq, via->ih);
bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq);
bus_dma_tag_destroy(via->parent_dmat);
bus_dma_tag_destroy(via->sgd_dmat);
free(via, M_DEVBUF);
return 0;
}
static device_method_t via_methods[] = {
DEVMETHOD(device_probe, via_probe),
DEVMETHOD(device_attach, via_attach),
DEVMETHOD(device_detach, via_detach),
{ 0, 0}
};

View File

@ -1161,7 +1161,8 @@ chn_init(pcm_channel *c, void *devinfo, int dir)
int
chn_kill(pcm_channel *c)
{
chn_trigger(c, PCMTRIG_ABORT);
if (c->flags & CHN_F_TRIGGERED)
chn_trigger(c, PCMTRIG_ABORT);
while (chn_removefeeder(c) == 0);
free(c->feeder->desc, M_DEVBUF);
free(c->feeder, M_DEVBUF);