| plan 9 kernel history: overview | file list | diff list |
1999/0415/alphapc/dma.c (diff list | history)
| 1999/0415/sys/src/9/alphapc/dma.c:9,31 – 1999/0423/sys/src/9/alphapc/dma.c:9,14 (short | long) | ||
| 1999/0415 | typedef struct DMA DMA; typedef struct DMAxfer DMAxfer; | |
| 1999/0415/sys/src/9/alphapc/dma.c:33,38 – 1999/0423/sys/src/9/alphapc/dma.c:16,22 | ||
| 1999/0415 | { ulong bpa; /* bounce buffer physical address */ void* bva; /* bounce buffer virtual address */ | |
| 1999/0423 | int blen; /* bounce buffer length */ | |
| 1999/0415 | void* va; /* virtual address destination/src */ long len; /* bytes to be transferred */ int isread; | |
| 1999/0415/sys/src/9/alphapc/dma.c:84,112 – 1999/0423/sys/src/9/alphapc/dma.c:68,109 | ||
| 1999/0415 | * initialisation routines of any devices which require DMA to ensure * the allocated bounce buffers are below the 16MB limit. */ | |
| 1999/0423 | int dmainit(int chan, int maxtransfer) | |
| 1999/0415 | { DMA *dp; DMAxfer *xp; | |
| 1999/0423 | if(maxtransfer > 64*1024) maxtransfer = 64*1024; | |
| 1999/0415 | dp = &dma[(chan>>2)&1]; chan = chan & 3; xp = &dp->x[chan]; | |
| 1999/0423 | if(xp->bva != nil){ if(xp->blen < maxtransfer) return 1; return 0; | |
| 1999/0415 | } | |
| 1999/0423 | xp->bva = xspanalloc(maxtransfer, BY2PG, 64*1024); if(xp->bva == nil) return 1; | |
| 1999/0415 | xp->bpa = PADDR(xp->bva); | |
| 1999/0423 | if(xp->bpa >= 16*MB){ /* * This will panic with the current * implementation of xspanalloc(). xfree(xp->bva); */ xp->bva = nil; return 1; } xp->blen = maxtransfer; | |
| 1999/0415 | xp->len = 0; xp->isread = 0; | |
| 1999/0423 | return 0; | |
| 1999/0415 | } /* | |
| 1999/0415/sys/src/9/alphapc/dma.c:133,140 – 1999/0423/sys/src/9/alphapc/dma.c:130,138 | ||
| 1999/0415 | /* * if this isn't kernel memory or crossing 64k boundary or above 16 meg | |
| 1999/0423 | * use the bounce buffer. | |
| 1999/0415 | */ | |
| 1999/0423 | #ifdef notdef | |
| 1999/0415 | pa = PADDR(va); if((((ulong)va)&0xF0000000) != KZERO || (pa&0xFFFF0000) != ((pa+len)&0xFFFF0000) | |
| 1999/0415/sys/src/9/alphapc/dma.c:141,148 – 1999/0423/sys/src/9/alphapc/dma.c:139,146 | ||
| 1999/0415 | || pa >= 16*MB) { if(xp->bva == nil) return -1; | |
| 1999/0423 | if(len > xp->blen) len = xp->blen; | |
| 1999/0415 | if(!isread) memmove(xp->bva, va, len); xp->va = va; | |
| 1999/0415/sys/src/9/alphapc/dma.c:152,168 – 1999/0423/sys/src/9/alphapc/dma.c:150,170 | ||
| 1999/0415 | } else xp->len = 0; | |
| 1999/0423 | #else pa = PCIWADDR(va); #endif /* notdef */ | |
| 1999/0415 | /* * this setup must be atomic */ | |
| 1999/0423 | ilock(dp); | |
| 1999/0415 | outb(dp->cbp, 0); /* set count & address to their first byte */ | |
| 1999/0423 | outb(dp->mode, mode); /* single mode dma (give CPU a chance at mem) */ | |
| 1999/0415 | outb(dp->addr[chan], pa>>dp->shift); /* set address */ outb(dp->addr[chan], pa>>(8+dp->shift)); | |
| 1999/0423 | outb(dp->page[chan], pa>>16); outb(0x400|dp->page[chan], pa>>24); | |
| 1999/0415 | outb(dp->count[chan], (len>>dp->shift)-1); /* set count */ outb(dp->count[chan], ((len>>dp->shift)-1)>>8); outb(dp->sbm, chan); /* enable the channel */ | |
| 1999/0423/sys/src/9/alphapc/dma.c:132,137 – 1999/0424/sys/src/9/alphapc/dma.c:132,138 (short | long) | ||
| 1999/0415 | * if this isn't kernel memory or crossing 64k boundary or above 16 meg | |
| 1999/0423 | * use the bounce buffer. | |
| 1999/0415 | */ | |
| 1999/0424 | print("va%lux+", va); | |
| 1999/0423 | #ifdef notdef | |
| 1999/0415 | pa = PADDR(va); if((((ulong)va)&0xF0000000) != KZERO | |
| 1999/0423/sys/src/9/alphapc/dma.c:151,157 – 1999/0424/sys/src/9/alphapc/dma.c:152,158 | ||
| 1999/0415 | else xp->len = 0; | |
| 1999/0423 | #else | |
| 1999/0424 | pa = ISAWADDR(va); | |
| 1999/0423 | #endif /* notdef */ | |
| 1999/0415 | /* | |
| 1999/0423/sys/src/9/alphapc/dma.c:164,174 – 1999/0424/sys/src/9/alphapc/dma.c:165,176 | ||
| 1999/0415 | outb(dp->addr[chan], pa>>dp->shift); /* set address */ outb(dp->addr[chan], pa>>(8+dp->shift)); | |
| 1999/0423 | outb(dp->page[chan], pa>>16); | |
| 1999/0424 | //outb(0x400|dp->page[chan], pa>>24); | |
| 1999/0415 | outb(dp->count[chan], (len>>dp->shift)-1); /* set count */ outb(dp->count[chan], ((len>>dp->shift)-1)>>8); outb(dp->sbm, chan); /* enable the channel */ iunlock(dp); | |
| 1999/0424 | print("pa%lux+", pa); | |
| 1999/0415 | return len; } | |
| 1999/0423/sys/src/9/alphapc/dma.c:206,211 – 1999/0424/sys/src/9/alphapc/dma.c:208,222 | ||
| 1999/0415 | ilock(dp); outb(dp->sbm, 4|chan); iunlock(dp); | |
| 1999/0424 | { int i; outb(dp->cbp, 0); i = inb(dp->addr[chan]); i |= inb(dp->addr[chan])<<8; i |= inb(dp->page[chan])<<16; i |= inb(0x400|dp->page[chan])<<24; print("X%uX+", i); } | |
| 1999/0415 | xp = &dp->x[chan]; if(xp->len == 0 || !xp->isread) | |
| 1999/0424/sys/src/9/alphapc/dma.c:85,90 – 1999/0501/sys/src/9/alphapc/dma.c:85,91 (short | long) | ||
| 1999/0423 | return 1; return 0; | |
| 1999/0415 | } | |
| 1999/0501 | outb(dp->mc, 0); | |
| 1999/0423 | xp->bva = xspanalloc(maxtransfer, BY2PG, 64*1024); if(xp->bva == nil) | |
| 1999/0424/sys/src/9/alphapc/dma.c:126,131 – 1999/0501/sys/src/9/alphapc/dma.c:127,135 | ||
| 1999/0415 | dp = &dma[(chan>>2)&1]; chan = chan & 3; | |
| 1999/0501 | //print("va%lux+", va); #define tryPCI #ifdef notdef | |
| 1999/0415 | xp = &dp->x[chan]; /* | |
| 1999/0424/sys/src/9/alphapc/dma.c:132,139 – 1999/0501/sys/src/9/alphapc/dma.c:136,141 | ||
| 1999/0415 | * if this isn't kernel memory or crossing 64k boundary or above 16 meg | |
| 1999/0423 | * use the bounce buffer. | |
| 1999/0415 | */ | |
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0415 | pa = PADDR(va); if((((ulong)va)&0xF0000000) != KZERO || (pa&0xFFFF0000) != ((pa+len)&0xFFFF0000) | |
| 1999/0424/sys/src/9/alphapc/dma.c:151,159 – 1999/0501/sys/src/9/alphapc/dma.c:153,165 | ||
| 1999/0415 | } else xp->len = 0; | |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0423 | #endif /* notdef */ | |
| 1999/0501 | #ifdef tryISA pa = ISAWADDR(va); #endif /* tryISA */ #ifdef tryPCI pa = PCIWADDR(va); #endif /* tryPCI */ | |
| 1999/0415 | /* * this setup must be atomic | |
| 1999/0424/sys/src/9/alphapc/dma.c:165,176 – 1999/0501/sys/src/9/alphapc/dma.c:171,184 | ||
| 1999/0415 | outb(dp->addr[chan], pa>>dp->shift); /* set address */ outb(dp->addr[chan], pa>>(8+dp->shift)); | |
| 1999/0423 | outb(dp->page[chan], pa>>16); | |
| 1999/0424 |
| |
| 1999/0501 | #ifdef tryPCI outb(0x400|dp->page[chan], pa>>24); #endif /* tryPCI */ | |
| 1999/0415 | outb(dp->count[chan], (len>>dp->shift)-1); /* set count */ outb(dp->count[chan], ((len>>dp->shift)-1)>>8); outb(dp->sbm, chan); /* enable the channel */ iunlock(dp); | |
| 1999/0424 |
| |
| 1999/0501 | //print("pa%lux+", pa); | |
| 1999/0415 | return len; } | |
| 1999/0424/sys/src/9/alphapc/dma.c:215,221 – 1999/0501/sys/src/9/alphapc/dma.c:223,229 | ||
| 1999/0424 | i |= inb(dp->addr[chan])<<8; i |= inb(dp->page[chan])<<16; i |= inb(0x400|dp->page[chan])<<24; | |
| 1999/0501 | //print("X%uX+", i); | |
| 1999/0424 | } | |
| 1999/0415 | xp = &dp->x[chan]; | |
| 1999/0501/sys/src/9/alphapc/dma.c:107,112 – 1999/0504/sys/src/9/alphapc/dma.c:107,142 (short | long) | ||
| 1999/0423 | return 0; | |
| 1999/0415 | } | |
| 1999/0504 | static void dmastatus(DMA *dp, int chan) { int a, l, s; ilock(dp); outb(dp->cbp, 0); a = inb(dp->addr[chan]); a |= inb(dp->addr[chan])<<8; a |= inb(dp->page[chan])<<16; a |= inb(0x400|dp->page[chan])<<24; outb(dp->cbp, 0); l = inb(dp->count[chan]); l |= inb(dp->count[chan])<<8; s = inb(dp->cmd); iunlock(dp); print("addr %uX len %uX stat %uX\n", a, l, s); } void xdmastatus(int chan) { DMA *dp; dp = &dma[(chan>>2)&1]; chan = chan & 3; dmastatus(dp, chan); } | |
| 1999/0415 | /* * setup a dma transfer. if the destination is not in kernel * memory, allocate a page for the transfer. | |
| 1999/0501/sys/src/9/alphapc/dma.c:174,184 – 1999/0504/sys/src/9/alphapc/dma.c:204,215 | ||
| 1999/0501 | #ifdef tryPCI outb(0x400|dp->page[chan], pa>>24); #endif /* tryPCI */ | |
| 1999/0504 | outb(dp->cbp, 0); /* set count & address to their first byte */ | |
| 1999/0415 | outb(dp->count[chan], (len>>dp->shift)-1); /* set count */ outb(dp->count[chan], ((len>>dp->shift)-1)>>8); outb(dp->sbm, chan); /* enable the channel */ iunlock(dp); | |
| 1999/0501 |
| |
| 1999/0504 | dmastatus(dp, chan); | |
| 1999/0415 | return len; } | |
| 1999/0501/sys/src/9/alphapc/dma.c:210,215 – 1999/0504/sys/src/9/alphapc/dma.c:241,247 | ||
| 1999/0415 | dp = &dma[(chan>>2)&1]; chan = chan & 3; | |
| 1999/0504 | dmastatus(dp, chan); | |
| 1999/0415 | /* * disable the channel */ | |
| 1999/0501/sys/src/9/alphapc/dma.c:216,230 – 1999/0504/sys/src/9/alphapc/dma.c:248,253 | ||
| 1999/0415 | ilock(dp); outb(dp->sbm, 4|chan); iunlock(dp); | |
| 1999/0424 |
| |
| 1999/0501 |
| |
| 1999/0424 |
| |
| 1999/0415 | xp = &dp->x[chan]; if(xp->len == 0 || !xp->isread) | |
| 1999/0504/sys/src/9/alphapc/dma.c:108,114 – 1999/0505/sys/src/9/alphapc/dma.c:108,114 (short | long) | ||
| 1999/0415 | } | |
| 1999/0504 | static void | |
| 1999/0505 | dmastatus(DMA *dp, int chan, char c) | |
| 1999/0504 | { int a, l, s; | |
| 1999/0504/sys/src/9/alphapc/dma.c:123,129 – 1999/0505/sys/src/9/alphapc/dma.c:123,129 | ||
| 1999/0504 | l |= inb(dp->count[chan])<<8; s = inb(dp->cmd); iunlock(dp); | |
| 1999/0505 | print("%c: addr %uX len %uX stat %uX\n", c, a, l, s); | |
| 1999/0504 | } void | |
| 1999/0504/sys/src/9/alphapc/dma.c:134,140 – 1999/0505/sys/src/9/alphapc/dma.c:134,140 | ||
| 1999/0504 | dp = &dma[(chan>>2)&1]; chan = chan & 3; | |
| 1999/0505 | dmastatus(dp, chan, 'X'); | |
| 1999/0504 | } | |
| 1999/0415 | /* | |
| 1999/0504/sys/src/9/alphapc/dma.c:209,215 – 1999/0505/sys/src/9/alphapc/dma.c:209,215 | ||
| 1999/0415 | outb(dp->count[chan], ((len>>dp->shift)-1)>>8); outb(dp->sbm, chan); /* enable the channel */ iunlock(dp); | |
| 1999/0504 |
| |
| 1999/0505 | dmastatus(dp, chan, 'S'); | |
| 1999/0415 | return len; } | |
| 1999/0504/sys/src/9/alphapc/dma.c:241,247 – 1999/0505/sys/src/9/alphapc/dma.c:241,247 | ||
| 1999/0415 | dp = &dma[(chan>>2)&1]; chan = chan & 3; | |
| 1999/0504 |
| |
| 1999/0505 | dmastatus(dp, chan, 'E'); | |
| 1999/0415 | /* * disable the channel */ | |
| 1999/0505/sys/src/9/alphapc/dma.c:3,9 – 1999/0506/sys/src/9/alphapc/dma.c:3,8 (short | long) | ||
| 1999/0415 | #include "mem.h" #include "dat.h" #include "fns.h" | |
| 1999/0505/sys/src/9/alphapc/dma.c:63,68 – 1999/0506/sys/src/9/alphapc/dma.c:62,86 | ||
| 1999/0415 | 1 }, }; | |
| 1999/0506 | static void dmastatus(DMA *dp, int chan, char c) { int a, l, s; ilock(dp); outb(dp->cbp, 0); a = inb(dp->addr[chan]); a |= inb(dp->addr[chan])<<8; a |= inb(dp->page[chan])<<16; a |= inb(0x400|dp->page[chan])<<24; outb(dp->cbp, 0); l = inb(dp->count[chan]); l |= inb(dp->count[chan])<<8; s = inb(dp->cmd); iunlock(dp); print("%c: addr %uX len %uX stat %uX\n", c, a, l, s); } | |
| 1999/0415 | /* * DMA must be in the first 16MB. This gets called early by the * initialisation routines of any devices which require DMA to ensure | |
| 1999/0505/sys/src/9/alphapc/dma.c:73,79 – 1999/0506/sys/src/9/alphapc/dma.c:91,107 | ||
| 1999/0415 | { DMA *dp; DMAxfer *xp; | |
| 1999/0506 | static int once; | |
| 1999/0415 | ||
| 1999/0506 | if(once == 0){ outb(dma[0].mc, 0); outb(dma[1].mc, 0); outb(dma[0].cmask, 0); outb(dma[1].cmask, 0); outb(dma[1].mode, 0xC0); once = 1; } | |
| 1999/0423 | if(maxtransfer > 64*1024) maxtransfer = 64*1024; | |
| 1999/0505/sys/src/9/alphapc/dma.c:85,91 – 1999/0506/sys/src/9/alphapc/dma.c:113,119 | ||
| 1999/0423 | return 1; return 0; | |
| 1999/0415 | } | |
| 1999/0501 |
| |
| 1999/0506 | //dmastatus(dp, chan, 'I'); | |
| 1999/0423 | xp->bva = xspanalloc(maxtransfer, BY2PG, 64*1024); if(xp->bva == nil) | |
| 1999/0505/sys/src/9/alphapc/dma.c:107,131 – 1999/0506/sys/src/9/alphapc/dma.c:135,140 | ||
| 1999/0423 | return 0; | |
| 1999/0415 | } | |
| 1999/0504 |
| |
| 1999/0505 |
| |
| 1999/0504 |
| |
| 1999/0505 |
| |
| 1999/0504 |
| |
| 1999/0505/sys/src/9/alphapc/dma.c:159,164 – 1999/0506/sys/src/9/alphapc/dma.c:168,176 | ||
| 1999/0415 | chan = chan & 3; | |
| 1999/0501 | //print("va%lux+", va); #define tryPCI | |
| 1999/0506 | #ifndef PCIWADDR #define PCIWADDR(va) PADDR(va) #endif /* PCIWADDR */ | |
| 1999/0501 | #ifdef notdef | |
| 1999/0415 | xp = &dp->x[chan]; | |
| 1999/0505/sys/src/9/alphapc/dma.c:209,215 – 1999/0506/sys/src/9/alphapc/dma.c:221,227 | ||
| 1999/0415 | outb(dp->count[chan], ((len>>dp->shift)-1)>>8); outb(dp->sbm, chan); /* enable the channel */ iunlock(dp); | |
| 1999/0505 |
| |
| 1999/0506 | //dmastatus(dp, chan, 'S'); | |
| 1999/0415 | return len; } | |
| 1999/0505/sys/src/9/alphapc/dma.c:241,247 – 1999/0506/sys/src/9/alphapc/dma.c:253,259 | ||
| 1999/0415 | dp = &dma[(chan>>2)&1]; chan = chan & 3; | |
| 1999/0505 |
| |
| 1999/0506 | //dmastatus(dp, chan, 'E'); | |
| 1999/0415 | /* * disable the channel */ | |
| 1999/0506/sys/src/9/alphapc/dma.c:4,9 – 1999/0507/sys/src/9/alphapc/dma.c:4,11 (short | long) | ||
| 1999/0415 | #include "dat.h" #include "fns.h" | |
| 1999/0507 | #include "io.h" | |
| 1999/0415 | typedef struct DMAport DMAport; typedef struct DMA DMA; typedef struct DMAxfer DMAxfer; | |
| 1999/0506/sys/src/9/alphapc/dma.c:166,171 – 1999/0507/sys/src/9/alphapc/dma.c:168,174 | ||
| 1999/0415 | dp = &dma[(chan>>2)&1]; chan = chan & 3; | |
| 1999/0507 | xp = &dp->x[chan]; | |
| 1999/0501 | //print("va%lux+", va); #define tryPCI | |
| 1999/0506 | #ifndef PCIWADDR | |
| 1999/0506/sys/src/9/alphapc/dma.c:172,178 – 1999/0507/sys/src/9/alphapc/dma.c:175,180 | ||
| 1999/0506 | #define PCIWADDR(va) PADDR(va) #endif /* PCIWADDR */ | |
| 1999/0501 | #ifdef notdef | |
| 1999/0415 |
| |
| 1999/0506/sys/src/9/alphapc/dma.c:201,206 – 1999/0507/sys/src/9/alphapc/dma.c:203,222 | ||
| 1999/0501 | #endif /* tryISA */ #ifdef tryPCI pa = PCIWADDR(va); | |
| 1999/0507 | if((((ulong)va)&0xF0000000) != KZERO){ if(xp->bva == nil) return -1; if(len > xp->blen) len = xp->blen; if(!isread) memmove(xp->bva, va, len); xp->va = va; xp->len = len; xp->isread = isread; pa = PCIWADDR(xp->bva); } else xp->len = 0; | |
| 1999/0501 | #endif /* tryPCI */ | |
| 1999/0415 | /* | |
| 1999/0507/sys/src/9/alphapc/dma.c:96,101 – 2000/0401/sys/src/9/alphapc/dma.c:96,105 (short | long) | ||
| 1999/0506 | static int once; | |
| 1999/0415 | ||
| 1999/0506 | if(once == 0){ | |
| 2000/0401 | if(ioalloc(0x00, 0x10, 0, "dma") < 0 || ioalloc(0x80, 0x10, 0, "dma") < 0 || ioalloc(0xd0, 0x10, 0, "dma") < 0) panic("dmainit"); | |
| 1999/0506 | outb(dma[0].mc, 0); outb(dma[1].mc, 0); outb(dma[0].cmask, 0); | |
| 2000/0401/sys/src/9/alphapc/dma.c:119,125 – 2001/1208/sys/src/9/alphapc/dma.c:119,125 (short | long) | ||
| 1999/0423 | return 1; return 0; | |
| 1999/0415 | } | |
| 1999/0506 |
| |
| 2001/1208 | dmastatus(dp, chan, 'I'); | |
| 1999/0423 | xp->bva = xspanalloc(maxtransfer, BY2PG, 64*1024); if(xp->bva == nil) | |
| 2000/0401/sys/src/9/alphapc/dma.c:241,247 – 2001/1208/sys/src/9/alphapc/dma.c:241,247 | ||
| 1999/0415 | outb(dp->count[chan], ((len>>dp->shift)-1)>>8); outb(dp->sbm, chan); /* enable the channel */ iunlock(dp); | |
| 1999/0506 |
| |
| 2001/1208 | dmastatus(dp, chan, 'S'); | |
| 1999/0415 | return len; } | |
| 2000/0401/sys/src/9/alphapc/dma.c:273,279 – 2001/1208/sys/src/9/alphapc/dma.c:273,279 | ||
| 1999/0415 | dp = &dma[(chan>>2)&1]; chan = chan & 3; | |
| 1999/0506 |
| |
| 2001/1208 | dmastatus(dp, chan, 'E'); | |
| 1999/0415 | /* * disable the channel */ | |
| 2001/1208/sys/src/9/alphapc/dma.c:119,125 – 2001/1210/sys/src/9/alphapc/dma.c:119,125 (short | long) | ||
| 1999/0423 | return 1; return 0; | |
| 1999/0415 | } | |
| 2001/1208 |
| |
| 2001/1210 | //dmastatus(dp, chan, 'I'); | |
| 1999/0423 | xp->bva = xspanalloc(maxtransfer, BY2PG, 64*1024); if(xp->bva == nil) | |
| 2001/1208/sys/src/9/alphapc/dma.c:241,247 – 2001/1210/sys/src/9/alphapc/dma.c:241,247 | ||
| 1999/0415 | outb(dp->count[chan], ((len>>dp->shift)-1)>>8); outb(dp->sbm, chan); /* enable the channel */ iunlock(dp); | |
| 2001/1208 |
| |
| 2001/1210 | //dmastatus(dp, chan, 'S'); | |
| 1999/0415 | return len; } | |
| 2001/1208/sys/src/9/alphapc/dma.c:273,279 – 2001/1210/sys/src/9/alphapc/dma.c:273,279 | ||
| 1999/0415 | dp = &dma[(chan>>2)&1]; chan = chan & 3; | |
| 2001/1208 |
| |
| 2001/1210 | //dmastatus(dp, chan, 'E'); | |
| 1999/0415 | /* * disable the channel */ | |