1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-15 10:17:20 +00:00

Extend the callback mechanism and add hooks to support PCI cards.

Remove a few unused variables.
This commit is contained in:
Luigi Rizzo 1998-12-31 07:34:01 +00:00
parent 172ea6ae6f
commit 4964edb0c6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=42192
11 changed files with 191 additions and 160 deletions

View File

@ -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,

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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));

View File

@ -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);