diff options
author | cinap_lenrek <cinap_lenrek@localhost> | 2011-05-18 19:57:31 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@localhost> | 2011-05-18 19:57:31 +0000 |
commit | b74418c2ce5c64ba39473e2eb50ea1112be63109 (patch) | |
tree | 06b3c26e33277e9f2c5e7a2d345d12efdf5d552e /sys/src/9/pc/dma.c | |
parent | e7e04b5cbbedfb1411fcc38b7e7f67db98a251c2 (diff) |
sb16: new approach, works in qemu
Diffstat (limited to 'sys/src/9/pc/dma.c')
-rw-r--r-- | sys/src/9/pc/dma.c | 57 |
1 files changed, 35 insertions, 22 deletions
diff --git a/sys/src/9/pc/dma.c b/sys/src/9/pc/dma.c index 7ecbc5f4a..4a81f516a 100644 --- a/sys/src/9/pc/dma.c +++ b/sys/src/9/pc/dma.c @@ -18,7 +18,7 @@ struct DMAxfer int blen; /* bounce buffer length */ void* va; /* virtual address destination/src */ long len; /* bytes to be transferred */ - int isread; + int flags; }; /* @@ -81,7 +81,7 @@ _i8237alloc(void) if(i8237dma > 2) i8237dma = 2; - bva = xspanalloc(64*1024*i8237dma, BY2PG, 64*1024); + bva = xspanalloc(64*1024*i8237dma, 0, 64*1024); if(bva == nil || PADDR(bva)+64*1024*i8237dma > 16*MB){ /* * This will panic with the current @@ -137,11 +137,38 @@ dmainit(int chan, int maxtransfer) xp->bpa = PADDR(xp->bva); xp->blen = maxtransfer; xp->len = 0; - xp->isread = 0; + xp->flags = 0; return 0; } +void* +dmabva(int chan) +{ + DMA *dp; + DMAxfer *xp; + + dp = &dma[(chan>>2)&1]; + chan = chan & 3; + xp = &dp->x[chan]; + return xp->bva; +} + +int +dmacount(int chan) +{ + int retval; + DMA *dp; + + dp = &dma[(chan>>2)&1]; + chan = chan & 3; + ilock(dp); + retval = inb(dp->count[chan]); + retval |= inb(dp->count[chan]) << 8; + iunlock(dp); + return ((retval<<dp->shift)+1) & 0xFFFF; +} + /* * setup a dma transfer. if the destination is not in kernel * memory, allocate a page for the transfer. @@ -153,7 +180,7 @@ dmainit(int chan, int maxtransfer) * boundaries) */ long -dmasetup(int chan, void *va, long len, int isread) +dmasetup(int chan, void *va, long len, int flags) { DMA *dp; ulong pa; @@ -175,11 +202,11 @@ dmasetup(int chan, void *va, long len, int isread) return -1; if(len > xp->blen) len = xp->blen; - if(!isread) + if(!(flags & DMAREAD)) memmove(xp->bva, va, len); xp->va = va; xp->len = len; - xp->isread = isread; + xp->flags = flags; pa = xp->bpa; } else @@ -189,7 +216,7 @@ dmasetup(int chan, void *va, long len, int isread) * this setup must be atomic */ ilock(dp); - mode = (isread ? 0x44 : 0x48) | chan; + mode = ((flags & DMAREAD) ? 0x44 : 0x48) | ((flags & DMALOOP) ? 0x10 : 0) | chan; outb(dp->mode, mode); /* single mode dma (give CPU a chance at mem) */ outb(dp->page[chan], pa>>16); outb(dp->cbp, 0); /* set count & address to their first byte */ @@ -238,7 +265,7 @@ dmaend(int chan) iunlock(dp); xp = &dp->x[chan]; - if(xp->len == 0 || !xp->isread) + if(xp->len == 0 || !(xp->flags & DMAREAD)) return; /* @@ -248,17 +275,3 @@ dmaend(int chan) xp->len = 0; } -/* -int -dmacount(int chan) -{ - int retval; - DMA *dp; - - dp = &dma[(chan>>2)&1]; - outb(dp->cbp, 0); - retval = inb(dp->count[chan]); - retval |= inb(dp->count[chan]) << 8; - return((retval<<dp->shift)+1); -} - */ |