M pc/audio.h => pc/audio.h +1 -1
@@ 6,7 6,7 @@ enum
SBswab = 0,
};
-#define seteisadma(a, b) dmainit(a);
+#define seteisadma(a, b) dmainit(a, Bufsize);
#define CACHELINESZ 8
#define UNCACHED(type, v) (type*)((ulong)(v))
M pc/devfloppy.c => pc/devfloppy.c +2 -2
@@ 144,8 144,6 @@ floppyreset(void)
FDrive *dp;
FType *t;
ulong maxtsize;
-
- dmainit(DMAchan);
floppysetup0(&fl);
@@ 161,6 159,8 @@ floppyreset(void)
maxtsize = t->tsize;
}
+ dmainit(DMAchan, maxtsize);
+
/*
* allocate the drive storage
*/
M pc/dma.c => pc/dma.c +25 -15
@@ 32,6 32,7 @@ struct DMAxfer
{
ulong bpa; /* bounce buffer physical address */
void* bva; /* bounce buffer virtual address */
+ int blen; /* bounce buffer length */
void* va; /* virtual address destination/src */
long len; /* bytes to be transferred */
int isread;
@@ 83,29 84,38 @@ DMA dma[2] = {
* initialisation routines of any devices which require DMA to ensure
* the allocated bounce buffers are below the 16MB limit.
*/
-void
-dmainit(int chan)
+int
+dmainit(int chan, int maxtransfer)
{
DMA *dp;
DMAxfer *xp;
- ulong v;
+
+ if(maxtransfer > 64*1024)
+ maxtransfer = 64*1024;
dp = &dma[(chan>>2)&1];
chan = chan & 3;
xp = &dp->x[chan];
- if(xp->bva != nil)
- return;
-
- v = (ulong)xalloc(BY2PG+BY2PG);
- if(v == 0 || PADDR(v) >= 16*MB){
- print("dmainit: chan %d: 0x%luX out of range\n", chan, v);
- xfree((void*)v);
- v = 0;
+ if(xp->bva != nil){
+ if(xp->blen < maxtransfer)
+ return 1;
+ return 0;
}
- xp->bva = (void*)ROUND(v, BY2PG);
+
+ xp->bva = xspanalloc(maxtransfer, BY2PG, 64*1024);
+ if(xp->bva == nil)
+ return 1;
xp->bpa = PADDR(xp->bva);
+ if(xp->bpa >= 16*MB){
+ xfree(xp->bva); /* doesn't work... */
+ xp->bva = nil;
+ return 1;
+ }
+ xp->blen = maxtransfer;
xp->len = 0;
xp->isread = 0;
+
+ return 0;
}
/*
@@ 132,7 142,7 @@ dmasetup(int chan, void *va, long len, int isread)
/*
* if this isn't kernel memory or crossing 64k boundary or above 16 meg
- * use the allocated low memory page.
+ * use the bounce buffer.
*/
pa = PADDR(va);
if((((ulong)va)&0xF0000000) != KZERO
@@ 140,8 150,8 @@ dmasetup(int chan, void *va, long len, int isread)
|| pa >= 16*MB) {
if(xp->bva == nil)
return -1;
- if(len > BY2PG)
- len = BY2PG;
+ if(len > xp->blen)
+ len = xp->blen;
if(!isread)
memmove(xp->bva, va, len);
xp->va = va;
M pc/fns.h => pc/fns.h +1 -1
@@ 17,7 17,7 @@ void delay(int);
int dmacount(int);
int dmadone(int);
void dmaend(int);
-void dmainit(int);
+int dmainit(int, int);
long dmasetup(int, void*, long, int);
#define evenaddr(x) /* x86 doesn't care */
void fpenv(FPsave*);