Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/tc - add mmap support
details: https://anonhg.NetBSD.org/src/rev/5ffade768226
branches: trunk
changeset: 487784:5ffade768226
user: gmcgarry <gmcgarry%NetBSD.org@localhost>
date: Mon Jun 12 22:40:20 2000 +0000
description:
- add mmap support
- correct bug which wouldn't free allocated DMA segments
diffstat:
sys/dev/tc/bba.c | 130 ++++++++++++++++++++++++++++++++++++------------------
1 files changed, 86 insertions(+), 44 deletions(-)
diffs (296 lines):
diff -r 0d59cff5a879 -r 5ffade768226 sys/dev/tc/bba.c
--- a/sys/dev/tc/bba.c Mon Jun 12 22:36:59 2000 +0000
+++ b/sys/dev/tc/bba.c Mon Jun 12 22:40:20 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bba.c,v 1.5 2000/06/05 23:02:04 gmcgarry Exp $ */
+/* $NetBSD: bba.c,v 1.6 2000/06/12 22:40:20 gmcgarry Exp $ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -63,14 +63,17 @@
#define DPRINTF(x)
#endif /* AUDIO_DEBUG */
+#define BBA_REGISTER_SHIFT 6
#define BBA_MAX_DMA_SEGMENTS 16
-#define BBA_REGISTER_SHIFT 6
+#define BBA_DMABUF_SIZE (BBA_MAX_DMA_SEGMENTS*PAGE_SIZE)
+#define BBA_DMABUF_ALIGN PAGE_SIZE
+#define BBA_DMABUF_BOUNDARY 0
struct bba_mem {
+ struct bba_mem *next;
bus_addr_t addr;
bus_size_t size;
caddr_t kva;
- struct bba_mem *next;
};
struct bba_dma_state {
@@ -138,10 +141,12 @@
void *bba_allocm __P((void *, int, size_t, int, int));
void bba_freem __P((void *, void *, int));
size_t bba_round_buffersize __P((void *, int, size_t));
+int bba_get_props __P((void *));
+int bba_mappage __P((void *, void *, int, int));
int bba_trigger_output __P((void *, void *, void *, int,
- void (*)(void *), void *, struct audio_params *));
+ void (*)(void *), void *, struct audio_params *));
int bba_trigger_input __P((void *, void *, void *, int,
- void (*)(void *), void *, struct audio_params *));
+ void (*)(void *), void *, struct audio_params *));
struct audio_hw_if sa_hw_if = {
am7930_open,
@@ -166,8 +171,8 @@
bba_allocm, /* md */
bba_freem, /* md */
bba_round_buffersize, /* md */
- 0,
- am7930_get_props,
+ bba_mappage,
+ bba_get_props,
bba_trigger_output, /* md */
bba_trigger_input /* md */
};
@@ -190,9 +195,9 @@
{
struct ioasicdev_attach_args *ia = aux;
- if (strcmp(ia->iada_modname, "isdn") != 0 &&
- strcmp(ia->iada_modname, "AMD79c30") != 0)
- return 0;
+ if (strcmp(ia->iada_modname, "isdn") != 0 &&
+ strcmp(ia->iada_modname, "AMD79c30") != 0)
+ return 0;
return 1;
}
@@ -214,7 +219,7 @@
/* get the bus space handle for codec */
if (bus_space_subregion(sc->sc_bst, sc->sc_bsh,
- ia->iada_offset, 0, &sc->sc_codec_bsh)) {
+ ia->iada_offset, 0, &sc->sc_codec_bsh)) {
printf("%s: unable to map device\n", asc->sc_dev.dv_xname);
return;
}
@@ -234,7 +239,7 @@
am7930_init(asc, AUDIOAMD_DMA_MODE);
ioasic_intr_establish(parent, ia->iada_cookie, TC_IPL_NONE,
- bba_intr, sc);
+ bba_intr, sc);
audio_attach_mi(&sa_hw_if, asc, &asc->sc_dev);
}
@@ -300,20 +305,23 @@
int rseg;
caddr_t kva;
struct bba_mem *m;
+ int w;
int state = 0;
DPRINTF(("bba_allocm: size = %d\n",size));
- if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &seg,
- 1, &rseg, BUS_DMA_NOWAIT)) {
+ w = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK;
+
+ if (bus_dmamem_alloc(sc->sc_dmat, size, BBA_DMABUF_ALIGN,
+ BBA_DMABUF_BOUNDARY, &seg, 1, &rseg, w)) {
printf("%s: can't allocate DMA buffer\n",
- asc->sc_dev.dv_xname);
+ asc->sc_dev.dv_xname);
goto bad;
}
state |= 1;
if (bus_dmamem_map(sc->sc_dmat, &seg, rseg, size,
- &kva, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
+ &kva, w | BUS_DMA_COHERENT)) {
printf("%s: can't map DMA buffer\n", asc->sc_dev.dv_xname);
goto bad;
}
@@ -351,11 +359,11 @@
caddr_t kva = (caddr_t)addr;
for (mp = &sc->sc_mem_head; *mp && (*mp)->kva != kva;
- mp = &(*mp)->next)
+ mp = &(*mp)->next)
/* nothing */ ;
m = *mp;
- if (m != NULL) {
- printf("bba_freem: freeing unallocted memory\n");
+ if (m == NULL) {
+ printf("bba_freem: freeing unallocated memory\n");
return;
}
*mp = m->next;
@@ -376,8 +384,7 @@
{
DPRINTF(("bba_round_buffersize: size=%d\n", size));
-#define BBA_BUFFERSIZE (BBA_MAX_DMA_SEGMENTS * PAGE_SIZE)
- return (size > BBA_BUFFERSIZE ? BBA_BUFFERSIZE : round_page(size));
+ return (size > BBA_DMABUF_SIZE ? BBA_DMABUF_SIZE : round_page(size));
}
@@ -457,27 +464,28 @@
int state = 0;
DPRINTF(("bba_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
- addr, start, end, blksize, intr, arg));
+ addr, start, end, blksize, intr, arg));
+
+ /* disable any DMA */
+ ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
+ ssr &= ~IOASIC_CSR_DMAEN_ISDN_T;
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
if (bus_dmamap_create(sc->sc_dmat, (char *)end - (char *)start,
- BBA_MAX_DMA_SEGMENTS, PAGE_SIZE, 0, BUS_DMA_NOWAIT, &d->dmam)) {
+ BBA_MAX_DMA_SEGMENTS, PAGE_SIZE, BBA_DMABUF_BOUNDARY,
+ BUS_DMA_NOWAIT, &d->dmam)) {
printf("bba_trigger_output: can't create DMA map\n");
goto bad;
}
state |= 1;
if (bus_dmamap_load(sc->sc_dmat, d->dmam, start,
- (char *)end - (char *)start, NULL, BUS_DMA_NOWAIT)) {
- printf("bba_trigger_output: can't load DMA map\n");
+ (char *)end - (char *)start, NULL, BUS_DMA_NOWAIT)) {
+ printf("bba_trigger_output: can't load DMA map\n");
goto bad;
}
state |= 2;
- /* disable any DMA */
- ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
- ssr &= ~IOASIC_CSR_DMAEN_ISDN_T;
- bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
-
d->intr = intr;
d->intr_arg = arg;
d->curseg = 1;
@@ -488,9 +496,9 @@
/* setup DMA pointer */
bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_X_DMAPTR,
- IOASIC_DMA_ADDR(phys));
+ IOASIC_DMA_ADDR(phys));
bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_X_NEXTPTR,
- IOASIC_DMA_ADDR(nphys));
+ IOASIC_DMA_ADDR(nphys));
/* kick off DMA */
ssr |= IOASIC_CSR_DMAEN_ISDN_T;
@@ -525,27 +533,28 @@
int state = 0;
DPRINTF(("bba_trigger_input: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
- addr, start, end, blksize, intr, arg));
+ addr, start, end, blksize, intr, arg));
+
+ /* disable any DMA */
+ ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
+ ssr &= ~IOASIC_CSR_DMAEN_ISDN_R;
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
if (bus_dmamap_create(sc->sc_dmat, (char *)end - (char *)start,
- BBA_MAX_DMA_SEGMENTS, PAGE_SIZE, 0, BUS_DMA_NOWAIT, &d->dmam)) {
+ BBA_MAX_DMA_SEGMENTS, PAGE_SIZE, BBA_DMABUF_BOUNDARY,
+ BUS_DMA_NOWAIT, &d->dmam)) {
printf("bba_trigger_input: can't create DMA map\n");
goto bad;
}
state |= 1;
if (bus_dmamap_load(sc->sc_dmat, d->dmam, start,
- (char *)end - (char *)start, NULL, BUS_DMA_NOWAIT)) {
+ (char *)end - (char *)start, NULL, BUS_DMA_NOWAIT)) {
printf("bba_trigger_input: can't load DMA map\n");
goto bad;
}
state |= 2;
- /* disable any DMA */
- ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
- ssr &= ~IOASIC_CSR_DMAEN_ISDN_R;
- bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
-
d->intr = intr;
d->intr_arg = arg;
d->curseg = 1;
@@ -556,9 +565,9 @@
/* setup DMA pointer */
bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_R_DMAPTR,
- IOASIC_DMA_ADDR(phys));
+ IOASIC_DMA_ADDR(phys));
bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_R_NEXTPTR,
- IOASIC_DMA_ADDR(nphys));
+ IOASIC_DMA_ADDR(nphys));
/* kick off DMA */
ssr |= IOASIC_CSR_DMAEN_ISDN_R;
@@ -594,7 +603,7 @@
d->curseg = (d->curseg+1) % d->dmam->dm_nsegs;
nphys = (tc_addr_t)d->dmam->dm_segs[d->curseg].ds_addr;
bus_space_write_4(sc->sc_bst, sc->sc_bsh,
- IOASIC_ISDN_X_NEXTPTR, IOASIC_DMA_ADDR(nphys));
+ IOASIC_ISDN_X_NEXTPTR, IOASIC_DMA_ADDR(nphys));
if (d->intr != NULL)
(*d->intr)(d->intr_arg);
}
@@ -603,7 +612,7 @@
d->curseg = (d->curseg+1) % d->dmam->dm_nsegs;
nphys = (tc_addr_t)d->dmam->dm_segs[d->curseg].ds_addr;
bus_space_write_4(sc->sc_bst, sc->sc_bsh,
- IOASIC_ISDN_R_NEXTPTR, IOASIC_DMA_ADDR(nphys));
+ IOASIC_ISDN_R_NEXTPTR, IOASIC_DMA_ADDR(nphys));
if (d->intr != NULL)
(*d->intr)(d->intr_arg);
}
@@ -613,6 +622,39 @@
return 0;
}
+int
+bba_get_props(addr)
+ void *addr;
+{
+ return (AUDIO_PROP_MMAP | am7930_get_props(addr));
+}
+
+int
+bba_mappage(addr, mem, offset, prot)
+ void *addr;
+ void *mem;
+ int offset;
+ int prot;
+{
+ struct bba_softc *sc = addr;
+ struct bba_mem **mp;
+ bus_dma_segment_t seg;
+ caddr_t kva = (caddr_t)mem;
+
+ for (mp = &sc->sc_mem_head; *mp && (*mp)->kva != kva;
+ mp = &(*mp)->next)
+ /* nothing */ ;
+ if (*mp == NULL || offset < 0) {
+ return -1;
+ }
+
+ seg.ds_addr = (*mp)->addr;
+ seg.ds_len = (*mp)->size;
+
+ return bus_dmamem_mmap(sc->sc_dmat, &seg, 1, offset,
+ prot, BUS_DMA_WAITOK);
+}
+
void
bba_input_conv(v, p, cc)
Home |
Main Index |
Thread Index |
Old Index