summaryrefslogtreecommitdiffstats
path: root/sys/dev/sound/isa/ess.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/sound/isa/ess.c')
-rw-r--r--sys/dev/sound/isa/ess.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/sys/dev/sound/isa/ess.c b/sys/dev/sound/isa/ess.c
index abef688..7b1bddf 100644
--- a/sys/dev/sound/isa/ess.c
+++ b/sys/dev/sound/isa/ess.c
@@ -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 @@ no:
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;
@@ -658,15 +678,6 @@ esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
}
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)
{
struct ess_chinfo *ch = data;
@@ -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 }
};
OpenPOWER on IntegriCloud