diff options
author | luigi <luigi@FreeBSD.org> | 1998-12-31 07:34:01 +0000 |
---|---|---|
committer | luigi <luigi@FreeBSD.org> | 1998-12-31 07:34:01 +0000 |
commit | 84df37382969fa58f3202f08724c722933d50f78 (patch) | |
tree | c7d4eb6dfaa7ecb8105b2dda10ec2d46a13b3520 /sys/i386/isa/snd/sound.c | |
parent | 7f0ec0256261ed83249787c12f155c77b1869216 (diff) | |
download | FreeBSD-src-84df37382969fa58f3202f08724c722933d50f78.zip FreeBSD-src-84df37382969fa58f3202f08724c722933d50f78.tar.gz |
Extend the callback mechanism and add hooks to support PCI cards.
Remove a few unused variables.
Diffstat (limited to 'sys/i386/isa/snd/sound.c')
-rw-r--r-- | sys/i386/isa/snd/sound.c | 155 |
1 files changed, 102 insertions, 53 deletions
diff --git a/sys/i386/isa/snd/sound.c b/sys/i386/isa/snd/sound.c index e233250..e9d8379 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)); |