summaryrefslogtreecommitdiffstats
path: root/sys/dev/sound/isa/sb8.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/sound/isa/sb8.c')
-rw-r--r--sys/dev/sound/isa/sb8.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/sys/dev/sound/isa/sb8.c b/sys/dev/sound/isa/sb8.c
index 21c3e6f..6d9154a 100644
--- a/sys/dev/sound/isa/sb8.c
+++ b/sys/dev/sound/isa/sb8.c
@@ -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 @@ no:
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 }
};
OpenPOWER on IntegriCloud