summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorJacob Meuser <jakemsr@cvs.openbsd.org>2008-10-02 18:29:41 +0000
committerJacob Meuser <jakemsr@cvs.openbsd.org>2008-10-02 18:29:41 +0000
commit2a7874f99de410f1f945ddabeab314800c8c52bd (patch)
treec58c904fb15668a834c26f90bb92f04e419836bc /sys/dev/pci
parent062f4c18445ce835506656182a95f522dbf7b5b8 (diff)
according to the alsa driver for these devices, the hardware provides
256 buffer descriptors, and the 256th descriptor is flakey. this driver uses one descriptor for each block of the buffer, so we need to make sure buffer size / block size < 256, or we will run out of usable descriptors. lets me play youtube videos via gnash on my auvia equipped machine. ok ratchov@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/auvia.c22
-rw-r--r--sys/dev/pci/auviavar.h5
2 files changed, 24 insertions, 3 deletions
diff --git a/sys/dev/pci/auvia.c b/sys/dev/pci/auvia.c
index b671cb43c40..f6307d4a960 100644
--- a/sys/dev/pci/auvia.c
+++ b/sys/dev/pci/auvia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auvia.c,v 1.41 2008/09/24 19:09:05 chl Exp $ */
+/* $OpenBSD: auvia.c,v 1.42 2008/10/02 18:29:40 jakemsr Exp $ */
/* $NetBSD: auvia.c,v 1.28 2002/11/04 16:38:49 kent Exp $ */
/*-
@@ -91,6 +91,7 @@ int auvia_get_port(void *, mixer_ctrl_t *);
int auvia_query_devinfo(void *, mixer_devinfo_t *);
void * auvia_malloc(void *, int, size_t, int, int);
void auvia_free(void *, void *, int);
+size_t auvia_round_buffersize(void *, int, size_t);
paddr_t auvia_mappage(void *, void *, off_t, int);
int auvia_get_props(void *);
int auvia_build_dma_ops(struct auvia_softc *, struct auvia_softc_chan *,
@@ -202,7 +203,7 @@ struct audio_hw_if auvia_hw_if = {
auvia_query_devinfo,
auvia_malloc,
auvia_free,
- NULL, /* auvia_round_buffersize */
+ auvia_round_buffersize,
auvia_mappage,
auvia_get_props,
auvia_trigger_output,
@@ -705,6 +706,10 @@ auvia_set_params(void *addr, int setmode, int usemode,
int
auvia_round_blocksize(void *addr, int blk)
{
+ struct auvia_softc *sc = addr;
+
+ if (sc->bufsize / blk > AUVIA_DMALIST_MAX)
+ blk = sc->bufsize / AUVIA_DMALIST_MAX + 1;
return ((blk + 31) & -32);
}
@@ -857,6 +862,15 @@ auvia_free(void *addr, void *ptr, int pool)
panic("auvia_free: trying to free unallocated memory");
}
+size_t
+auvia_round_buffersize(void *addr, int direction, size_t bufsize)
+{
+ struct auvia_softc *sc = addr;
+
+ sc->bufsize = bufsize;
+ return bufsize;
+}
+
paddr_t
auvia_mappage(void *addr, void *mem, off_t off, int prot)
{
@@ -901,6 +915,10 @@ auvia_build_dma_ops(struct auvia_softc *sc, struct auvia_softc_chan *ch,
s = p->map->dm_segs[0].ds_addr;
l = (vaddr_t)end - (vaddr_t)start;
segs = howmany(l, blksize);
+ if (segs > AUVIA_DMALIST_MAX) {
+ panic("%s: build_dma_ops: too many DMA segments",
+ sc->sc_dev.dv_xname);
+ }
if (segs > ch->sc_dma_op_count) {
/* if old list was too small, free it */
diff --git a/sys/dev/pci/auviavar.h b/sys/dev/pci/auviavar.h
index 93904ccb69f..d83879ab9c4 100644
--- a/sys/dev/pci/auviavar.h
+++ b/sys/dev/pci/auviavar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: auviavar.h,v 1.9 2008/06/26 05:42:17 ray Exp $ */
+/* $OpenBSD: auviavar.h,v 1.10 2008/10/02 18:29:40 jakemsr Exp $ */
/* $NetBSD: auviavar.h,v 1.1 2000/03/31 04:45:29 tsarna Exp $ */
/*-
@@ -62,10 +62,13 @@ struct auvia_softc {
struct ac97_host_if host_if;
struct ac97_codec_if *codec_if;
+ int bufsize;
struct auvia_dma *sc_dmas;
struct auvia_softc_chan sc_play, sc_record;
};
+#define AUVIA_DMALIST_MAX 255
+
#endif