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:
parent
b47ce7f5cb
commit
306f91b60b
@ -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 }
|
||||
};
|
||||
|
@ -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 }
|
||||
};
|
||||
|
@ -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 }
|
||||
};
|
||||
|
@ -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 }
|
||||
};
|
||||
|
@ -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 }
|
||||
};
|
||||
|
@ -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 }
|
||||
};
|
||||
|
@ -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),
|
||||
|
@ -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 },
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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, ®id,
|
||||
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, ®id,
|
||||
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 }
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 }
|
||||
};
|
||||
|
@ -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 }
|
||||
};
|
||||
|
@ -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, ®id,
|
||||
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}
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user