diff options
author | jmg <jmg@FreeBSD.org> | 1997-09-18 07:47:03 +0000 |
---|---|---|
committer | jmg <jmg@FreeBSD.org> | 1997-09-18 07:47:03 +0000 |
commit | 5280f97f953f261edc638240462e6c394f0b326b (patch) | |
tree | 526b5df60d6dc30bd18b9c3cb99357963b2cd9c1 /sys/i386/isa/snd/sound.c | |
parent | 1754071cd4379522b965738c1e339a06907577b6 (diff) | |
download | FreeBSD-src-5280f97f953f261edc638240462e6c394f0b326b.zip FreeBSD-src-5280f97f953f261edc638240462e6c394f0b326b.tar.gz |
update Luigi's driver to poll interface (Peter, you might want to check
that I've done this properly, it does work though :) )...
a few minor fixes to code
part-Submitted-by: Luigi
Diffstat (limited to 'sys/i386/isa/snd/sound.c')
-rw-r--r-- | sys/i386/isa/snd/sound.c | 133 |
1 files changed, 66 insertions, 67 deletions
diff --git a/sys/i386/isa/snd/sound.c b/sys/i386/isa/snd/sound.c index fcd5e39..844f760 100644 --- a/sys/i386/isa/snd/sound.c +++ b/sys/i386/isa/snd/sound.c @@ -51,6 +51,7 @@ */ #include <i386/isa/snd/sound.h> +#include <sys/poll.h> #if NPCM > 0 /* from "snd.h" */ @@ -75,7 +76,7 @@ static d_mmap_t sndmmap; static struct cdevsw snd_cdevsw = { sndopen, sndclose, sndread, sndwrite, sndioctl, nxstop, nxreset, nxdevtotty, - sndselect, sndmmap, nxstrategy, "snd", + sndpoll, sndmmap, nxstrategy, "snd", NULL, -1, }; @@ -271,7 +272,7 @@ print_isadev_info(struct isa_device *d, char *s) { if (d == NULL ) return ; - printf("%s%d at 0x%x irq %d drq %d mem 0x%x flags 0x%x en %d confl %d\n", + printf("%s%d at 0x%x irq %d drq %d mem %p flags 0x%x en %d confl %d\n", d->id_driver ? d->id_driver->name : "NONAME", d->id_unit, (u_short)(d->id_iobase), ffs(d->id_irq) - 1 , @@ -380,7 +381,8 @@ sndopen(dev_t i_dev, int flags, int mode, struct proc * p) default: if (d->open == NULL) { - printf("open: missing for unit %d\n", unit ); + printf("open: bad unit %d, perhaps you want unit %d ?\n", + unit, unit+1 ); return (ENXIO) ; } else return d->open(i_dev, flags, mode, p); @@ -724,7 +726,7 @@ sndioctl(dev_t i_dev, int cmd, caddr_t arg, int mode, struct proc * p) break ; case AIOSYNC: - printf("AIOSYNC chan 0x%03x pos %d unimplemented\n", + printf("AIOSYNC chan 0x%03lx pos %ld unimplemented\n", ((snd_sync_parm *)arg)->chan, ((snd_sync_parm *)arg)->pos); break; @@ -772,13 +774,13 @@ sndioctl(dev_t i_dev, int cmd, caddr_t arg, int mode, struct proc * p) ask_init(d); break ; case SNDCTL_DSP_RESET: - printf("dsp reset\n"); + DDB(printf("dsp reset\n")); dsp_wrabort(d); dsp_rdabort(d); break ; case SNDCTL_DSP_SYNC: - printf("dsp sync\n"); + DDB(printf("dsp sync\n")); splx(s); snd_sync(d, 1, d->bufsize - 4); /* DMA does not start with <4 bytes */ break ; @@ -850,8 +852,10 @@ sndioctl(dev_t i_dev, int cmd, caddr_t arg, int mode, struct proc * p) int bytes, count; bytes = *(int *)arg & 0xffff ; count = ( *(int *)arg >> 16) & 0xffff ; - if (bytes < 7 || bytes > 15) - return EINVAL ; + if (bytes < 7) + bytes = 7 ; + if (bytes > 15) + bytes = 15 ; d->play_blocksize = d->rec_blocksize = min ( 1<< bytes, d->dbuf_in.bufsize) ; count = d->dbuf_in.bufsize / d->play_blocksize ; @@ -923,76 +927,71 @@ sndioctl(dev_t i_dev, int cmd, caddr_t arg, int mode, struct proc * p) } int -sndselect(dev_t i_dev, int rw, struct proc * p) +sndpoll(dev_t i_dev, int events, struct proc *p) { + int lim ; + int revents = 0; int dev, unit, c = 1 /* default: success */ ; snddev_info *d ; u_long flags; dev = minor(i_dev); d = get_snddev_info(dev, &unit); - DEB(printf("sndselect dev 0x%04x rw 0x%08x\n",i_dev, rw)); + DEB(printf("sndpoll dev 0x%04x rw 0x%08x\n",i_dev, events)); if (d == NULL ) { printf("select: unit %d not configured\n", unit ); - return (ENXIO) ; + return ((events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)) + | POLLHUP); } - if (d->select == NULL) - return 1 ; /* always success ? */ - else if (d->select != sndselect ) - return d->select(i_dev, rw, p); - else { - /* handle it here with the generic code */ - - int lim ; - - /* - * if the user selected a block size, then we want to use the - * device as a block device, and select will return ready when - * we have a full block. - * In all other cases, select will return when 1 byte is ready. - */ - lim = 1; - switch(rw) { - case FWRITE : - if ( d->flags & SND_F_HAS_SIZE ) - lim = d->play_blocksize ; - /* XXX fix the test here for half duplex devices */ - if (1 /* write is compatible with current mode */) { - flags = spltty(); - if (d->flags & SND_F_WR_DMA) - dsp_wr_dmaupdate(d); - c = d->dbuf_out.fl ; - if (c < lim) /* no space available */ - selrecord(p, & (d->wsel)); - splx(flags); - } - return c < lim ? 0 : 1 ; - - case FREAD : - if ( d->flags & SND_F_HAS_SIZE ) - lim = d->rec_blocksize ; - /* XXX fix the test here */ - if (1 /* read is compatible with current mode */) { - flags = spltty(); - if ( !(d->flags & SND_F_RD_DMA) ) /* dma idle, restart it */ - dsp_rdintr(d); - else - dsp_rd_dmaupdate(d); - c = d->dbuf_in.rl ; - if (c < lim) /* no data available */ - selrecord(p, & (d->rsel)); - splx(flags); - } - DEB(printf("sndselect on read: %d >= %d flags 0x%08x\n", - c, lim, d->flags)); - return c < lim ? 0 : 1 ; + if (d->poll == NULL) + /* is this correct hear? */ + return ((events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)) + | POLLHUP); + else if (d->poll != sndpoll ) + return d->poll(i_dev, events, p); - case 0 : - DDB(printf("select on exceptions, unimplemented\n")); - return 1; - } + /* handle it here with the generic code */ + + /* + * if the user selected a block size, then we want to use the + * device as a block device, and select will return ready when + * we have a full block. + * In all other cases, select will return when 1 byte is ready. + */ + lim = 1; + flags = spltty(); + /* XXX fix the test here for half duplex devices */ + if (events & (POLLOUT | POLLWRNORM)) { + if ( d->flags & SND_F_HAS_SIZE ) + lim = d->play_blocksize ; + if (d->flags & SND_F_WR_DMA) + dsp_wr_dmaupdate(d); + c = d->dbuf_out.fl ; + if (c < lim) /* no space available */ + selrecord(p, & (d->wsel)); + else + revents |= events & (POLLOUT | POLLWRNORM); + } + + /* XXX fix the test here */ + if (events & (POLLIN | POLLRDNORM)) { + if ( d->flags & SND_F_HAS_SIZE ) + lim = d->rec_blocksize ; + if ( !(d->flags & SND_F_RD_DMA) ) /* dma idle, restart it */ + dsp_rdintr(d); + else + dsp_rd_dmaupdate(d); + c = d->dbuf_in.rl ; + if (c < lim) /* no data available */ + selrecord(p, & (d->rsel)); + else + revents |= events & (POLLIN | POLLRDNORM); + DEB(printf("sndpoll on read: %d >= %d flags 0x%08lx\n", c, lim, + d->flags)); } - return ENXIO ; /* notreached */ + splx(flags); + + return revents; } /* @@ -1021,7 +1020,7 @@ sndmmap(dev_t dev, int offset, int nprot) { snddev_info *d = get_snddev_info(dev, NULL); - DEB(printf("sndmmap d 0x%08x dev 0x%04x ofs 0x%08x nprot 0x%08x\n", + DEB(printf("sndmmap d %p dev 0x%04x ofs 0x%08x nprot 0x%08x\n", d, dev, offset, nprot)); if (d == NULL || nprot & PROT_EXEC) |