| plan 9 kernel history: overview | file list | diff list |
1991/0318/power/devbit3.c (diff list | history)
| 1991/0318/sys/src/9/power/devbit3.c:1,218 – 1991/0411/sys/src/9/power/devbit3.c:1,218 (short | long | prev | next) | ||
| 1990/0324 | #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "errno.h" #include "devtab.h" #include "io.h" static struct { QLock; | |
| 1990/06061 | QLock buflock; | |
| 1990/0324 | int open; char buf[10*1024]; }bit3; #define BIT3ADDR ((Bit3msg**)(KZERO+0x7C)) #define BIT3HOLD ((ulong*)(KZERO+0x78)) #define BIT3INTR ((char*)(UNCACHED|0x17c12001)) enum { RESET, READ, WRITE, }; void bit3send(Bit3msg *bp, ulong cmd, void *addr, ulong count) { do; while(*BIT3ADDR); bp->cmd = cmd; bp->addr = (ulong)addr; bp->count = count; *BIT3ADDR = bp; wbflush(); do; while(*BIT3HOLD); *BIT3INTR = 0x20; } void bit3reset(void) { *BIT3HOLD = 0; *BIT3ADDR = 0; qlock(&bit3); qunlock(&bit3); } void bit3init(void) { } Chan* bit3attach(char *spec) { return devattach('3', spec); } Chan* bit3clone(Chan *c, Chan *nc) { return devclone(c, nc); } int bit3walk(Chan *c, char *name) { | |
| 1990/11211 | if(c->qid.path != CHDIR) | |
| 1990/0324 | return 0; if(strcmp(name, "bit3") == 0){ | |
| 1990/11211 | c->qid.path = 1; | |
| 1990/0324 | return 1; } return 0; } void bit3stat(Chan *c, char *dp) { print("bit3stat\n"); | |
| 1990/11211 | error(Egreg); | |
| 1990/0324 | } Chan* bit3open(Chan *c, int omode) { Bit3msg *bp; | |
| 1990/0608 | bp = &((User*)(u->p->upage->pa|KZERO))->kbit3; | |
| 1990/11211 | if(c->qid.path!=1 || omode!=ORDWR) error(Eperm); | |
| 1990/0324 | qlock(&bit3); if(bit3.open){ qunlock(&bit3); | |
| 1990/11211 | error(Einuse); | |
| 1990/0324 | } bit3send(bp, RESET, 0, 0); bit3.open = 1; qunlock(&bit3); c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; } void bit3create(Chan *c, char *name, int omode, ulong perm) { | |
| 1990/11211 | error(Eperm); | |
| 1990/0324 | } void bit3close(Chan *c) { qlock(&bit3); bit3.open = 0; qunlock(&bit3); } /* * Read and write use physical addresses if they can, which they usually can. * Most I/O is from devmnt, which has local buffers. Therefore just check * that buf is in KSEG0 and is at an even address. The only killer is that * DMA counts from the bit3 device are mod 256, so devmnt must use oversize * buffers. */ long | |
| 1991/0411 | bit3read(Chan *c, void *buf, long n, ulong offset) | |
| 1990/0324 | { Bit3msg *bp; int docpy; | |
| 1990/11211 | switch(c->qid.path){ | |
| 1990/0324 | case 1: if(n > sizeof bit3.buf) | |
| 1990/11211 | error(Egreg); | |
| 1990/06061 | if((((ulong)buf)&(KSEGM|3)) == KSEG0){ /* * use supplied buffer, no need to lock for reply */ | |
| 1990/0608 | bp = &((User*)(u->p->upage->pa|KZERO))->kbit3; bp->rcount = 0; | |
| 1990/06061 | qlock(&bit3); | |
| 1990/0324 | bit3send(bp, READ, buf, n); | |
| 1990/06061 | qunlock(&bit3); do n = bp->rcount; while(n == 0); }else{ /* * use bit3 buffer. lock the buffer till the reply */ | |
| 1990/0608 | bp = &((User*)(u->p->upage->pa|KZERO))->ubit3; bp->rcount = 0; | |
| 1990/06061 | qlock(&bit3.buflock); qlock(&bit3); | |
| 1990/0324 | bit3send(bp, READ, bit3.buf, n); | |
| 1990/06061 | qunlock(&bit3); do n = bp->rcount; while(n == 0); | |
| 1991/0318 | memmove(buf, bit3.buf, n); | |
| 1990/06061 | qunlock(&bit3.buflock); } | |
| 1990/0324 | return n; } | |
| 1990/11211 | error(Egreg); | |
| 1990/0324 | return 0; } long | |
| 1991/0411 | bit3write(Chan *c, void *buf, long n, ulong offset) | |
| 1990/0324 | { Bit3msg *bp; | |
| 1990/11211 | switch(c->qid.path){ | |
| 1990/0324 | case 1: if(n > sizeof bit3.buf) | |
| 1990/11211 | error(Egreg); | |
| 1990/06061 | if((((ulong)buf)&(KSEGM|3)) == KSEG0){ | |
| 1990/0608 | bp = &((User*)(u->p->upage->pa|KZERO))->kbit3; | |
| 1990/06061 | qlock(&bit3); | |
| 1990/0324 | bit3send(bp, WRITE, buf, n); | |
| 1990/06061 | qunlock(&bit3); }else{ | |
| 1990/0608 | bp = &((User*)(u->p->upage->pa|KZERO))->ubit3; | |
| 1990/06061 | qlock(&bit3.buflock); | |
| 1990/0608 | ||
| 1990/06061 | qlock(&bit3); | |
| 1991/0318 | memmove(bit3.buf, buf, n); | |
| 1990/0324 | bit3send(bp, WRITE, bit3.buf, n); | |
| 1990/0608 | do; while(*BIT3ADDR); | |
| 1990/06061 | qunlock(&bit3); | |
| 1990/0608 | ||
| 1990/06061 | qunlock(&bit3.buflock); | |
| 1990/0324 | } return n; } | |
| 1990/11211 | error(Egreg); | |
| 1990/0324 | return 0; } void bit3remove(Chan *c) { | |
| 1990/11211 | error(Eperm); | |
| 1990/0324 | } void bit3wstat(Chan *c, char *dp) { | |
| 1990/11211 | error(Eperm); | |
| 1990/0324 | } | |