int blen; /* bounce buffer length */
void* va; /* virtual address destination/src */
long len; /* bytes to be transferred */
- int isread;
+ int flags;
};
/*
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
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.
* boundaries)
*/
long
-dmasetup(int chan, void *va, long len, int isread)
+dmasetup(int chan, void *va, long len, int flags)
{
DMA *dp;
ulong pa;
* if this isn't kernel memory or crossing 64k boundary or above 16 meg
* use the bounce buffer.
*/
- if((ulong)va < KZERO
+ if((uintptr)va < KZERO
|| ((pa=PADDR(va))&0xFFFF0000) != ((pa+len)&0xFFFF0000)
|| pa >= 16*MB){
if(xp->bva == nil)
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
xp->len = 0;
+ mode = ((flags & DMAREAD) ? 0x44 : 0x48) | /* read or write */
+ ((flags & DMALOOP) ? 0x10 : 0) | /* auto init mode */
+ chan;
+
/*
* this setup must be atomic
*/
ilock(dp);
- mode = (isread ? 0x44 : 0x48) | chan;
- outb(dp->mode, mode); /* single mode dma (give CPU a chance at mem) */
+ outb(dp->mode, mode);
outb(dp->page[chan], pa>>16);
outb(dp->cbp, 0); /* set count & address to their first byte */
outb(dp->addr[chan], pa>>dp->shift); /* set address */
iunlock(dp);
xp = &dp->x[chan];
- if(xp->len == 0 || !xp->isread)
+ if(xp->len == 0 || !(xp->flags & DMAREAD))
return;
/*
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);
-}
- */