From 4964edb0c637affdc4f9d850a1d576efd447de07 Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Thu, 31 Dec 1998 07:34:01 +0000 Subject: [PATCH] Extend the callback mechanism and add hooks to support PCI cards. Remove a few unused variables. --- sys/dev/pcm/isa/mss.c | 33 +++----- sys/dev/pcm/isa/sb.c | 5 -- sys/dev/sound/isa/mss.c | 33 +++----- sys/dev/sound/isa/sb.c | 5 -- sys/dev/sound/isa/sb16.c | 5 -- sys/dev/sound/isa/sb8.c | 5 -- sys/i386/isa/snd/ad1848.c | 33 +++----- sys/i386/isa/snd/dmabuf.c | 59 +++++++++++---- sys/i386/isa/snd/sb_dsp.c | 5 -- sys/i386/isa/snd/sound.c | 155 +++++++++++++++++++++++++------------- sys/i386/isa/snd/sound.h | 13 ++++ 11 files changed, 191 insertions(+), 160 deletions(-) diff --git a/sys/dev/pcm/isa/mss.c b/sys/dev/pcm/isa/mss.c index 56021d91f73..660e0eb6612 100644 --- a/sys/dev/pcm/isa/mss.c +++ b/sys/dev/pcm/isa/mss.c @@ -56,7 +56,7 @@ static int mss_probe(struct isa_device *dev); static int mss_attach(struct isa_device *dev); -static d_open_t mss_open; +d_open_t mss_open; /* this is a generic full-duplex open routine */ static d_close_t mss_close; static d_ioctl_t mss_ioctl; static irq_proc_t mss_intr; @@ -270,7 +270,7 @@ mss_attach(struct isa_device *dev) return 0; } -static int +int mss_open(dev_t dev, int flags, int mode, struct proc * p) { int unit; @@ -642,12 +642,14 @@ gus_write(int io_base, u_char reg, u_char value) outb(io_base + 5, value); } +#if 0 static void gus_writew(int io_base, u_char reg, u_short value) { outb(io_base + 3, reg); outb(io_base + 4, value); } +#endif static u_char gus_read(int io_base, u_char reg) @@ -656,13 +658,14 @@ gus_read(int io_base, u_char reg) return inb(io_base+5); } +#if 0 static u_short gus_readw(int io_base, u_char reg) { outb(io_base+3, reg); return inw(io_base+4); } - +#endif /* * AD_WAIT_INIT waits if we are initializing the board and @@ -828,22 +831,6 @@ mss_set_recsrc(snddev_info *d, int mask) return 0; } -/* - * mixer conversion table: from 0..100 scale to codec values - * - * I don't understand what's this for... maybe achieve a log-scale - * volume control ? - */ - -static char mix_cvt[101] = { - 0, 1, 3, 7,10,13,16,19,21,23,26,28,30,32,34,35,37,39,40,42, - 43,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,64,65, - 65,66,67,68,69,70,70,71,72,73,73,74,75,75,76,77,77,78,79,79, - 80,81,81,82,82,83,84,84,85,85,86,86,87,87,88,88,89,89,90,90, - 91,91,92,92,93,93,94,94,95,95,96,96,96,97,97,98,98,98,99,99, - 100 -}; - /* * there are differences in the mixer depending on the actual sound * card. @@ -1402,9 +1389,9 @@ cs423x_probe(u_long csn, u_long vend_id) u_long id = vend_id & 0xff00ffff; if ( id == 0x3700630e ) s = "CS4237" ; - if ( id == 0x2500630e ) + else if ( id == 0x2500630e ) s = "CS4235" ; - else if ( id == 0x3500630e || id == 0x3600630e ) + else if ( id == 0x3600630e ) s = "CS4236" ; else if ( id == 0x3500630e ) s = "CS4236B" ; @@ -1487,7 +1474,7 @@ cs423x_attach(u_long csn, u_long vend_id, char *name, tmp_d.bd_id = MD_CS4237 ; break; - case 0x2500630e: /* AOpen AW37 */ + case 0x2500630e: /* AOpen AW37, CS4235 */ tmp_d.bd_id = MD_CS4237 ; break ; @@ -1692,7 +1679,9 @@ opti925_attach(u_long csn, u_long vend_id, char *name, pcmattach(dev); } +#if 0 static void gus_mem_cfg(snddev_info *tmp); +#endif static char *guspnp_probe(u_long csn, u_long vend_id); static void guspnp_attach(u_long csn, u_long vend_id, char *name, diff --git a/sys/dev/pcm/isa/sb.c b/sys/dev/pcm/isa/sb.c index 4bd58256643..3c77f1f12bc 100644 --- a/sys/dev/pcm/isa/sb.c +++ b/sys/dev/pcm/isa/sb.c @@ -382,7 +382,6 @@ sb_callback(snddev_info *d, int reason) * the proper initialization for each one. */ if (PLAIN_SB16(d->bd_flags)) { - u_char c, c1 ; /* the original SB16 (non-PnP, or PnP, or Vibra16C) * can do full duplex using one 16-bit channel @@ -500,7 +499,6 @@ sb_callback(snddev_info *d, int reason) * the second one takes the next... * The default is to be ready for play. */ - int swap = 0 ; DEB(printf("start %s -- now dma %d:%d\n", rd ? "rd" : "wr", d->dbuf_out.chan, d->dbuf_in.chan);); @@ -767,8 +765,6 @@ sb_dsp_init(snddev_info *d, struct isa_device *dev) break ; } else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) { - u_char cfg; - u_char bits; int rev = ess_minor & 0xf; if (rev >= 8) @@ -1232,7 +1228,6 @@ ess1868_attach(u_long csn, u_long vend_id, char *name, { struct pnp_cinfo d ; snddev_info tmp_d ; /* patched copy of the basic snddev_info */ - int the_irq = 0 ; tmp_d = sb_op_desc; snddev_last_probed = &tmp_d; diff --git a/sys/dev/sound/isa/mss.c b/sys/dev/sound/isa/mss.c index 56021d91f73..660e0eb6612 100644 --- a/sys/dev/sound/isa/mss.c +++ b/sys/dev/sound/isa/mss.c @@ -56,7 +56,7 @@ static int mss_probe(struct isa_device *dev); static int mss_attach(struct isa_device *dev); -static d_open_t mss_open; +d_open_t mss_open; /* this is a generic full-duplex open routine */ static d_close_t mss_close; static d_ioctl_t mss_ioctl; static irq_proc_t mss_intr; @@ -270,7 +270,7 @@ mss_attach(struct isa_device *dev) return 0; } -static int +int mss_open(dev_t dev, int flags, int mode, struct proc * p) { int unit; @@ -642,12 +642,14 @@ gus_write(int io_base, u_char reg, u_char value) outb(io_base + 5, value); } +#if 0 static void gus_writew(int io_base, u_char reg, u_short value) { outb(io_base + 3, reg); outb(io_base + 4, value); } +#endif static u_char gus_read(int io_base, u_char reg) @@ -656,13 +658,14 @@ gus_read(int io_base, u_char reg) return inb(io_base+5); } +#if 0 static u_short gus_readw(int io_base, u_char reg) { outb(io_base+3, reg); return inw(io_base+4); } - +#endif /* * AD_WAIT_INIT waits if we are initializing the board and @@ -828,22 +831,6 @@ mss_set_recsrc(snddev_info *d, int mask) return 0; } -/* - * mixer conversion table: from 0..100 scale to codec values - * - * I don't understand what's this for... maybe achieve a log-scale - * volume control ? - */ - -static char mix_cvt[101] = { - 0, 1, 3, 7,10,13,16,19,21,23,26,28,30,32,34,35,37,39,40,42, - 43,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,64,65, - 65,66,67,68,69,70,70,71,72,73,73,74,75,75,76,77,77,78,79,79, - 80,81,81,82,82,83,84,84,85,85,86,86,87,87,88,88,89,89,90,90, - 91,91,92,92,93,93,94,94,95,95,96,96,96,97,97,98,98,98,99,99, - 100 -}; - /* * there are differences in the mixer depending on the actual sound * card. @@ -1402,9 +1389,9 @@ cs423x_probe(u_long csn, u_long vend_id) u_long id = vend_id & 0xff00ffff; if ( id == 0x3700630e ) s = "CS4237" ; - if ( id == 0x2500630e ) + else if ( id == 0x2500630e ) s = "CS4235" ; - else if ( id == 0x3500630e || id == 0x3600630e ) + else if ( id == 0x3600630e ) s = "CS4236" ; else if ( id == 0x3500630e ) s = "CS4236B" ; @@ -1487,7 +1474,7 @@ cs423x_attach(u_long csn, u_long vend_id, char *name, tmp_d.bd_id = MD_CS4237 ; break; - case 0x2500630e: /* AOpen AW37 */ + case 0x2500630e: /* AOpen AW37, CS4235 */ tmp_d.bd_id = MD_CS4237 ; break ; @@ -1692,7 +1679,9 @@ opti925_attach(u_long csn, u_long vend_id, char *name, pcmattach(dev); } +#if 0 static void gus_mem_cfg(snddev_info *tmp); +#endif static char *guspnp_probe(u_long csn, u_long vend_id); static void guspnp_attach(u_long csn, u_long vend_id, char *name, diff --git a/sys/dev/sound/isa/sb.c b/sys/dev/sound/isa/sb.c index 4bd58256643..3c77f1f12bc 100644 --- a/sys/dev/sound/isa/sb.c +++ b/sys/dev/sound/isa/sb.c @@ -382,7 +382,6 @@ sb_callback(snddev_info *d, int reason) * the proper initialization for each one. */ if (PLAIN_SB16(d->bd_flags)) { - u_char c, c1 ; /* the original SB16 (non-PnP, or PnP, or Vibra16C) * can do full duplex using one 16-bit channel @@ -500,7 +499,6 @@ sb_callback(snddev_info *d, int reason) * the second one takes the next... * The default is to be ready for play. */ - int swap = 0 ; DEB(printf("start %s -- now dma %d:%d\n", rd ? "rd" : "wr", d->dbuf_out.chan, d->dbuf_in.chan);); @@ -767,8 +765,6 @@ sb_dsp_init(snddev_info *d, struct isa_device *dev) break ; } else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) { - u_char cfg; - u_char bits; int rev = ess_minor & 0xf; if (rev >= 8) @@ -1232,7 +1228,6 @@ ess1868_attach(u_long csn, u_long vend_id, char *name, { struct pnp_cinfo d ; snddev_info tmp_d ; /* patched copy of the basic snddev_info */ - int the_irq = 0 ; tmp_d = sb_op_desc; snddev_last_probed = &tmp_d; diff --git a/sys/dev/sound/isa/sb16.c b/sys/dev/sound/isa/sb16.c index 4bd58256643..3c77f1f12bc 100644 --- a/sys/dev/sound/isa/sb16.c +++ b/sys/dev/sound/isa/sb16.c @@ -382,7 +382,6 @@ sb_callback(snddev_info *d, int reason) * the proper initialization for each one. */ if (PLAIN_SB16(d->bd_flags)) { - u_char c, c1 ; /* the original SB16 (non-PnP, or PnP, or Vibra16C) * can do full duplex using one 16-bit channel @@ -500,7 +499,6 @@ sb_callback(snddev_info *d, int reason) * the second one takes the next... * The default is to be ready for play. */ - int swap = 0 ; DEB(printf("start %s -- now dma %d:%d\n", rd ? "rd" : "wr", d->dbuf_out.chan, d->dbuf_in.chan);); @@ -767,8 +765,6 @@ sb_dsp_init(snddev_info *d, struct isa_device *dev) break ; } else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) { - u_char cfg; - u_char bits; int rev = ess_minor & 0xf; if (rev >= 8) @@ -1232,7 +1228,6 @@ ess1868_attach(u_long csn, u_long vend_id, char *name, { struct pnp_cinfo d ; snddev_info tmp_d ; /* patched copy of the basic snddev_info */ - int the_irq = 0 ; tmp_d = sb_op_desc; snddev_last_probed = &tmp_d; diff --git a/sys/dev/sound/isa/sb8.c b/sys/dev/sound/isa/sb8.c index 4bd58256643..3c77f1f12bc 100644 --- a/sys/dev/sound/isa/sb8.c +++ b/sys/dev/sound/isa/sb8.c @@ -382,7 +382,6 @@ sb_callback(snddev_info *d, int reason) * the proper initialization for each one. */ if (PLAIN_SB16(d->bd_flags)) { - u_char c, c1 ; /* the original SB16 (non-PnP, or PnP, or Vibra16C) * can do full duplex using one 16-bit channel @@ -500,7 +499,6 @@ sb_callback(snddev_info *d, int reason) * the second one takes the next... * The default is to be ready for play. */ - int swap = 0 ; DEB(printf("start %s -- now dma %d:%d\n", rd ? "rd" : "wr", d->dbuf_out.chan, d->dbuf_in.chan);); @@ -767,8 +765,6 @@ sb_dsp_init(snddev_info *d, struct isa_device *dev) break ; } else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) { - u_char cfg; - u_char bits; int rev = ess_minor & 0xf; if (rev >= 8) @@ -1232,7 +1228,6 @@ ess1868_attach(u_long csn, u_long vend_id, char *name, { struct pnp_cinfo d ; snddev_info tmp_d ; /* patched copy of the basic snddev_info */ - int the_irq = 0 ; tmp_d = sb_op_desc; snddev_last_probed = &tmp_d; diff --git a/sys/i386/isa/snd/ad1848.c b/sys/i386/isa/snd/ad1848.c index 56021d91f73..660e0eb6612 100644 --- a/sys/i386/isa/snd/ad1848.c +++ b/sys/i386/isa/snd/ad1848.c @@ -56,7 +56,7 @@ static int mss_probe(struct isa_device *dev); static int mss_attach(struct isa_device *dev); -static d_open_t mss_open; +d_open_t mss_open; /* this is a generic full-duplex open routine */ static d_close_t mss_close; static d_ioctl_t mss_ioctl; static irq_proc_t mss_intr; @@ -270,7 +270,7 @@ mss_attach(struct isa_device *dev) return 0; } -static int +int mss_open(dev_t dev, int flags, int mode, struct proc * p) { int unit; @@ -642,12 +642,14 @@ gus_write(int io_base, u_char reg, u_char value) outb(io_base + 5, value); } +#if 0 static void gus_writew(int io_base, u_char reg, u_short value) { outb(io_base + 3, reg); outb(io_base + 4, value); } +#endif static u_char gus_read(int io_base, u_char reg) @@ -656,13 +658,14 @@ gus_read(int io_base, u_char reg) return inb(io_base+5); } +#if 0 static u_short gus_readw(int io_base, u_char reg) { outb(io_base+3, reg); return inw(io_base+4); } - +#endif /* * AD_WAIT_INIT waits if we are initializing the board and @@ -828,22 +831,6 @@ mss_set_recsrc(snddev_info *d, int mask) return 0; } -/* - * mixer conversion table: from 0..100 scale to codec values - * - * I don't understand what's this for... maybe achieve a log-scale - * volume control ? - */ - -static char mix_cvt[101] = { - 0, 1, 3, 7,10,13,16,19,21,23,26,28,30,32,34,35,37,39,40,42, - 43,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,64,65, - 65,66,67,68,69,70,70,71,72,73,73,74,75,75,76,77,77,78,79,79, - 80,81,81,82,82,83,84,84,85,85,86,86,87,87,88,88,89,89,90,90, - 91,91,92,92,93,93,94,94,95,95,96,96,96,97,97,98,98,98,99,99, - 100 -}; - /* * there are differences in the mixer depending on the actual sound * card. @@ -1402,9 +1389,9 @@ cs423x_probe(u_long csn, u_long vend_id) u_long id = vend_id & 0xff00ffff; if ( id == 0x3700630e ) s = "CS4237" ; - if ( id == 0x2500630e ) + else if ( id == 0x2500630e ) s = "CS4235" ; - else if ( id == 0x3500630e || id == 0x3600630e ) + else if ( id == 0x3600630e ) s = "CS4236" ; else if ( id == 0x3500630e ) s = "CS4236B" ; @@ -1487,7 +1474,7 @@ cs423x_attach(u_long csn, u_long vend_id, char *name, tmp_d.bd_id = MD_CS4237 ; break; - case 0x2500630e: /* AOpen AW37 */ + case 0x2500630e: /* AOpen AW37, CS4235 */ tmp_d.bd_id = MD_CS4237 ; break ; @@ -1692,7 +1679,9 @@ opti925_attach(u_long csn, u_long vend_id, char *name, pcmattach(dev); } +#if 0 static void gus_mem_cfg(snddev_info *tmp); +#endif static char *guspnp_probe(u_long csn, u_long vend_id); static void guspnp_attach(u_long csn, u_long vend_id, char *name, diff --git a/sys/i386/isa/snd/dmabuf.c b/sys/i386/isa/snd/dmabuf.c index da963090622..66f94ac5526 100644 --- a/sys/i386/isa/snd/dmabuf.c +++ b/sys/i386/isa/snd/dmabuf.c @@ -4,7 +4,7 @@ * This file implements the new DMA routines for the sound driver. * AUTO DMA MODE (ISA DMA SIDE). * - * Copyright by Luigi Rizzo - 1997-98 + * Copyright by Luigi Rizzo - 1997-99 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -108,7 +108,10 @@ dsp_wr_dmadone(snddev_info *d) { snd_dbuf *b = & (d->dbuf_out) ; - dsp_wr_dmaupdate(b); + if (d->special_dma) + d->callback(d, SND_CB_WR | SND_CB_DMAUPDATE) ; + else + dsp_wr_dmaupdate(b); /* * XXX here it would be more efficient to record if there * actually is a sleeping process, but this should still work. @@ -191,7 +194,10 @@ dsp_wrintr(snddev_info *d) * at high speed, it might well be that the count * changes in the meantime. So we try to update b->rl */ - dsp_wr_dmaupdate(b) ; + if (d->special_dma) + d->callback(d, SND_CB_WR | SND_CB_DMAUPDATE) ; + else + dsp_wr_dmaupdate(b) ; l = min(b->rl, d->play_blocksize ); l &= DMA_ALIGN_MASK ; /* realign things */ b->dl = l; /* record previous transfer size */ @@ -252,7 +258,10 @@ dsp_write_body(snddev_info *d, struct uio *buf) while ( (n = buf->uio_resid) ) { l = min (n, bsz); /* at most n bytes ... */ s = spltty(); /* no interrupts here ... */ - dsp_wr_dmaupdate(b); + if (d->special_dma) + d->callback(d, SND_CB_WR | SND_CB_DMAUPDATE) ; + else + dsp_wr_dmaupdate(b); l = min( l, b->fl ); /* no more than avail. space */ DEB(printf("dsp_write_body: prepare %d bytes out of %d\n", l,n)); /* @@ -406,7 +415,10 @@ dsp_rd_dmadone(snddev_info *d) { snd_dbuf *b = & (d->dbuf_in) ; - dsp_rd_dmaupdate(b); + if (d->special_dma) + d->callback(d, SND_CB_RD | SND_CB_DMAUPDATE) ; + else + dsp_rd_dmaupdate(b); wakeup(b) ; /* wakeup possibly sleeping processes */ if (b->sel.si_pid && ( !(d->flags & SND_F_HAS_SIZE) || b->rl >= d->rec_blocksize ) ) @@ -530,7 +542,10 @@ dsp_read_body(snddev_info *d, struct uio *buf) DEB(printf("dsp_read_body: start waiting for %d bytes\n", n)); l = min (n, bsz); s = spltty(); /* no interrupts here ! */ - dsp_rd_dmaupdate(b); + if (d->special_dma) + d->callback(d, SND_CB_RD | SND_CB_DMAUPDATE) ; + else + dsp_rd_dmaupdate(b); l = min( l, b->rl ); /* no more than avail. data */ if (l == 0) { int timeout; @@ -643,7 +658,8 @@ reset_dbuf(snd_dbuf *b, int chan) chan = B_WRITE | B_RAW ; else chan = B_READ | B_RAW ; - isa_dmastart( chan , b->buf, b->bufsize, b->chan); + if (b->chan != 4 && b->chan < 8) /* XXX hack for pci... */ + isa_dmastart( chan , b->buf, b->bufsize, b->chan); } /* @@ -663,10 +679,14 @@ snd_sync(snddev_info *d, int chan, int threshold) for (;;) { s=spltty(); - if ( chan==1 ) - dsp_wr_dmaupdate(b); - else - dsp_rd_dmaupdate(b); + if (d->special_dma) + d->callback(d, (chan==1? SND_CB_WR:SND_CB_RD) | SND_CB_DMAUPDATE); + else { + if ( chan==1 ) + dsp_wr_dmaupdate(b); + else + dsp_rd_dmaupdate(b); + } if ( (chan == 1 && b->fl <= threshold) || (chan == 2 && b->rl <= threshold) ) { ret = tsleep((caddr_t)b, PRIBIO|PCATCH, "sndsyn", 1); @@ -701,13 +721,15 @@ dsp_wrabort(snddev_info *d, int restart) d->flags &= ~ SND_F_WRITING ; if (d->callback) d->callback(d, SND_CB_WR | SND_CB_ABORT); - isa_dmastop(b->chan) ; + if (!d->special_dma) + isa_dmastop(b->chan) ; dsp_wr_dmadone(d); DEB(printf("dsp_wrabort: stopped, %d bytes left\n", b->rl)); } missing = b->rl; - isa_dmadone(B_WRITE, b->buf, b->bufsize, b->chan); /*free chan */ + if (!d->special_dma) + isa_dmadone(B_WRITE, b->buf, b->bufsize, b->chan); /*free chan */ reset_dbuf(b, restart ? SND_CHAN_WR : SND_CHAN_NONE); splx(s); return missing; @@ -726,11 +748,13 @@ dsp_rdabort(snddev_info *d, int restart) d->flags &= ~ SND_F_READING ; if (d->callback) d->callback(d, SND_CB_RD | SND_CB_ABORT); - isa_dmastop(b->chan) ; + if (!d->special_dma) + isa_dmastop(b->chan) ; dsp_rd_dmadone(d); } missing = b->rl ; - isa_dmadone(B_READ, b->buf, b->bufsize, b->chan); + if (!d->special_dma) + isa_dmadone(B_READ, b->buf, b->bufsize, b->chan); reset_dbuf(b, restart ? SND_CHAN_RD : SND_CHAN_NONE); splx(s); return missing; @@ -758,7 +782,10 @@ snd_flush(snddev_info *d) * still pending output data. */ ret = tsleep( (caddr_t)b, PRIBIO|PCATCH, "dmafl1", hz); - dsp_wr_dmaupdate(b); + if (d->special_dma) + d->callback(d, SND_CB_WR | SND_CB_DMAUPDATE); + else + dsp_wr_dmaupdate(b); DEB( printf("snd_sync: now rl : fl %d : %d\n", b->rl, b->fl ) ); if (ret == EINTR) { printf("tsleep returns %d\n", ret); diff --git a/sys/i386/isa/snd/sb_dsp.c b/sys/i386/isa/snd/sb_dsp.c index 4bd58256643..3c77f1f12bc 100644 --- a/sys/i386/isa/snd/sb_dsp.c +++ b/sys/i386/isa/snd/sb_dsp.c @@ -382,7 +382,6 @@ sb_callback(snddev_info *d, int reason) * the proper initialization for each one. */ if (PLAIN_SB16(d->bd_flags)) { - u_char c, c1 ; /* the original SB16 (non-PnP, or PnP, or Vibra16C) * can do full duplex using one 16-bit channel @@ -500,7 +499,6 @@ sb_callback(snddev_info *d, int reason) * the second one takes the next... * The default is to be ready for play. */ - int swap = 0 ; DEB(printf("start %s -- now dma %d:%d\n", rd ? "rd" : "wr", d->dbuf_out.chan, d->dbuf_in.chan);); @@ -767,8 +765,6 @@ sb_dsp_init(snddev_info *d, struct isa_device *dev) break ; } else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) { - u_char cfg; - u_char bits; int rev = ess_minor & 0xf; if (rev >= 8) @@ -1232,7 +1228,6 @@ ess1868_attach(u_long csn, u_long vend_id, char *name, { struct pnp_cinfo d ; snddev_info tmp_d ; /* patched copy of the basic snddev_info */ - int the_irq = 0 ; tmp_d = sb_op_desc; snddev_last_probed = &tmp_d; diff --git a/sys/i386/isa/snd/sound.c b/sys/i386/isa/snd/sound.c index e233250e60b..e9d83797caa 100644 --- a/sys/i386/isa/snd/sound.c +++ b/sys/i386/isa/snd/sound.c @@ -229,7 +229,7 @@ synthprobe(struct isa_device * dev) } /* - * this is the generic attach routine + * this is the ISA part of the generic attach routine */ int @@ -239,7 +239,9 @@ pcmattach(struct isa_device * dev) struct isa_device *dvp; int stat = 0; dev_t isadev; +#ifdef DEVFS void *cookie; +#endif dev->id_ointr = pcmintr; @@ -284,19 +286,64 @@ pcmattach(struct isa_device * dev) isa_dma_acquire(d->dbuf_out.chan); if (FULL_DUPLEX(d)) isa_dma_acquire(d->dbuf_in.chan); + + isadev = makedev(CDEV_MAJOR, 0); + cdevsw_add(&isadev, &snd_cdevsw, NULL); + + /* + * should try and find a suitable value for id_id, otherwise + * the interrupt is not registered and dispatched properly. + * This is important for PnP devices, where "dev" is built on + * the fly and many field are not initialized. + */ + if (dev->id_driver == NULL) { + dev->id_driver = &pcmdriver ; + dvp=find_isadev(isa_devtab_tty, &pcmdriver, 0); + if (dvp) + dev->id_id = dvp->id_id; + } + + /* + * call the generic part of the attach + */ + pcminit(d, dev->id_unit); + /* + * and finally, call the device attach routine + * XXX I should probably use d->attach(dev) + */ + stat = snddev_last_probed->attach(dev); +#if 0 + /* + * XXX hooks for synt support. Try probe and attach... + */ + if (d->synth_base && opl3_probe(dev) ) { + opl3_attach(dev); + } +#endif + snddev_last_probed = NULL ; + + return stat ; +} + +/* + * This is the generic init routine + */ +int +pcminit(snddev_info *d, int unit) +{ + void *cookie; + /* * initialize standard parameters for the device. This can be * overridden by device-specific configurations but better do * here the generic things. */ + d->magic = MAGIC(unit); /* debugging... */ d->play_speed = d->rec_speed = 8000 ; d->play_blocksize = d->rec_blocksize = 2048 ; d->play_fmt = d->rec_fmt = AFMT_MU_LAW ; - isadev = makedev(CDEV_MAJOR, 0); - cdevsw_add(&isadev, &snd_cdevsw, NULL); - #ifdef DEVFS #ifndef GID_GAMES #define GID_SND UID_ROOT @@ -342,40 +389,10 @@ pcmattach(struct isa_device * dev) if (cookie) devfs_makelink(cookie, "sequencer"); #endif #endif /* DEVFS */ - - /* - * should try and find a suitable value for id_id, otherwise - * the interrupt is not registered and dispatched properly. - * This is important for PnP devices, where "dev" is built on - * the fly and many field are not initialized. - */ - if (dev->id_driver == NULL) { - dev->id_driver = &pcmdriver ; - dvp=find_isadev(isa_devtab_tty, &pcmdriver, 0); - if (dvp) - dev->id_id = dvp->id_id; - } - - d->magic = MAGIC(dev->id_unit); /* debugging... */ - /* - * and finally, call the device attach routine - * XXX I should probably use d->attach(dev) - */ - stat = snddev_last_probed->attach(dev); -#if 0 - /* - * XXX hooks for synt support. Try probe and attach... - */ - if (d->synth_base && opl3_probe(dev) ) { - opl3_attach(dev); - } -#endif - snddev_last_probed = NULL ; - #if NAPM > 0 - init_sound_apm(dev->id_unit); + init_sound_apm(unit); #endif - return stat ; + return 0 ; } int midiattach(struct isa_device * dev) { return 0 ; } @@ -785,8 +802,12 @@ sndioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct proc * p) * we start with the new ioctl interface. */ case AIONWRITE : /* how many bytes can write ? */ - if (d->dbuf_out.dl) - dsp_wr_dmaupdate(&(d->dbuf_out)); + if (d->dbuf_out.dl) { + if (d->special_dma) + d->callback(d, SND_CB_WR | SND_CB_DMAUPDATE) ; + else + dsp_wr_dmaupdate(&(d->dbuf_out)); + } *(int *)arg = d->dbuf_out.fl; break; @@ -872,7 +893,7 @@ sndioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct proc * p) break ; case AIOSYNC: - printf("AIOSYNC chan 0x%03lx pos %d unimplemented\n", + printf("AIOSYNC chan 0x%03lx pos %lu unimplemented\n", ((snd_sync_parm *)arg)->chan, ((snd_sync_parm *)arg)->pos); break; @@ -880,8 +901,12 @@ sndioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct proc * p) * here follow the standard ioctls (filio.h etc.) */ case FIONREAD : /* get # bytes to read */ - if ( d->dbuf_in.dl ) - dsp_rd_dmaupdate(&(d->dbuf_in)); + if ( d->dbuf_in.dl ) { + if (d->special_dma) + d->callback(d, SND_CB_RD | SND_CB_DMAUPDATE) ; + else + dsp_rd_dmaupdate(&(d->dbuf_in)); + } *(int *)arg = d->dbuf_in.rl; break; @@ -1038,8 +1063,12 @@ sndioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct proc * p) { audio_buf_info *a = (audio_buf_info *)arg; snd_dbuf *b = &(d->dbuf_in); - if (b->dl) - dsp_rd_dmaupdate( b ); + if (b->dl) { + if (d->special_dma) + d->callback(d, SND_CB_RD | SND_CB_DMAUPDATE) ; + else + dsp_rd_dmaupdate( b ); + } a->bytes = d->dbuf_in.fl ; a->fragments = 1 ; a->fragstotal = b->bufsize / d->rec_blocksize ; @@ -1052,8 +1081,12 @@ sndioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct proc * p) { audio_buf_info *a = (audio_buf_info *)arg; snd_dbuf *b = &(d->dbuf_out); - if (b->dl) - dsp_wr_dmaupdate( b ); + if (b->dl) { + if (d->special_dma) + d->callback(d, SND_CB_WR | SND_CB_DMAUPDATE) ; + else + dsp_wr_dmaupdate( b ); + } a->bytes = d->dbuf_out.fl ; a->fragments = 1 ; a->fragstotal = b->bufsize / d->play_blocksize ; @@ -1065,8 +1098,12 @@ sndioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct proc * p) { count_info *a = (count_info *)arg; snd_dbuf *b = &(d->dbuf_in); - if (b->dl) - dsp_rd_dmaupdate( b ); + if (b->dl) { + if (d->special_dma) + d->callback(d, SND_CB_RD | SND_CB_DMAUPDATE) ; + else + dsp_rd_dmaupdate( b ); + } a->bytes = b->total; a->blocks = (b->total - b->prev_total + d->rec_blocksize -1 ) / d->rec_blocksize ; @@ -1079,8 +1116,12 @@ sndioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct proc * p) { count_info *a = (count_info *)arg; snd_dbuf *b = &(d->dbuf_out); - if (b->dl) - dsp_wr_dmaupdate( b ); + if (b->dl) { + if (d->special_dma) + d->callback(d, SND_CB_WR | SND_CB_DMAUPDATE) ; + else + dsp_wr_dmaupdate( b ); + } a->bytes = b->total; a->blocks = (b->total - b->prev_total /* +d->play_blocksize -1*/ ) / d->play_blocksize ; @@ -1168,8 +1209,12 @@ sndselect(dev_t i_dev, int rw, struct proc * p) /* XXX fix the test here for half duplex devices */ if (1 /* write is compatible with current mode */) { flags = spltty(); - if (d->dbuf_out.dl) - dsp_wr_dmaupdate(&(d->dbuf_out)); + if (d->dbuf_out.dl) { + if (d->special_dma) + d->callback(d, SND_CB_WR | SND_CB_DMAUPDATE) ; + else + dsp_wr_dmaupdate(&(d->dbuf_out)); + } c = d->dbuf_out.fl ; if (c < lim) /* no space available */ selrecord(p, & (d->wsel)); @@ -1186,8 +1231,12 @@ sndselect(dev_t i_dev, int rw, struct proc * p) flags = spltty(); if ( d->dbuf_in.dl == 0 ) /* dma idle, restart it */ dsp_rdintr(d); - else - dsp_rd_dmaupdate(&(d->dbuf_in)); + else { + if (d->special_dma) + d->callback(d, SND_CB_RD | SND_CB_DMAUPDATE) ; + else + dsp_rd_dmaupdate(&(d->dbuf_in)); + } c = d->dbuf_in.rl ; if (c < lim) /* no data available */ selrecord(p, & (d->rsel)); diff --git a/sys/i386/isa/snd/sound.h b/sys/i386/isa/snd/sound.h index e6d1eb9e5e7..8edd1147601 100644 --- a/sys/i386/isa/snd/sound.h +++ b/sys/i386/isa/snd/sound.h @@ -151,6 +151,14 @@ struct _snddev_info { #define SND_CB_STOP 0x03 /* stop dma op */ #define SND_CB_ABORT 0x04 /* abort dma op */ #define SND_CB_INIT 0x05 /* init board parameters */ + + /* + * callback extensions + */ +#define SND_CB_DMADONE 0x10 +#define SND_CB_DMAUPDATE 0x11 +#define SND_CB_DMASTOP 0x12 + /* init can only be called with int enabled and * no pending DMA activity. */ @@ -288,6 +296,10 @@ struct _snddev_info { int synth_base ; /* base for the synth */ int synth_type ; /* type of synth */ void *device_data ; /* just in case it is needed...*/ + int special_dma ; + /* when this is set, dsp_wr_dmaupdate etc. + * are processed using callback extensions. + */ } ; /* @@ -431,6 +443,7 @@ int pcmprobe(struct isa_device * dev); int midiprobe(struct isa_device * dev); int synthprobe(struct isa_device * dev); int pcmattach(struct isa_device * dev); +int pcminit(snddev_info *d, int unit); int midiattach(struct isa_device * dev); int synthattach(struct isa_device * dev);