|
|
1.1 ! root 1: /*% cyntax -c -DKERNEL % && cc -c -DKERNEL % ! 2: * Metheus 3610 driver via dr11-w for 9Vr2 ! 3: */ ! 4: #include "sys/param.h" ! 5: #include "sys/conf.h" ! 6: #include "sys/user.h" ! 7: #include "sys/buf.h" ! 8: #include "sys/ubaddr.h" ! 9: #include "sys/om.h" ! 10: #define OMTIMEOUT 15 /* seconds */ ! 11: int omopen(), omclose(), omread(), omwrite(), omioctl(); ! 12: struct cdevsw omcdev=cdinit(omopen, omclose, omread, omwrite, nodev); ! 13: int omcnt; /* defined in conf */ ! 14: extern struct ubaddr omaddr[]; /* defined in conf */ ! 15: #define OPEN 1 /* somebody has the device open */ ! 16: #define RUNNING 2 /* dma in progress */ ! 17: #define LATE 4 /* dma ready to time out */ ! 18: #define NOTIME 8 /* don't bother with timeout */ ! 19: int omtiming; /* timeout exists */ ! 20: /* ! 21: * dr11-w hardware registers ! 22: */ ! 23: struct omreg{ ! 24: short wc; ! 25: short addr; ! 26: short csr; ! 27: short data; ! 28: }; ! 29: /* ! 30: * csr bits ! 31: */ ! 32: #define ERROR 0100000 ! 33: #define ATTN 020000 ! 34: #define READY 0200 ! 35: #define IENABLE 0100 ! 36: #define XMEM 060 ! 37: #define xmem(a) (((a)>>12)&XMEM) ! 38: #define WAKEUP 010 ! 39: #define READ 02 ! 40: #define GO 01 ! 41: int omtimeout(); ! 42: omopen(dev, flags){ ! 43: register d=minor(dev); ! 44: register struct om *p=&om[d]; ! 45: if(d>=omcnt ! 46: || p->flag&OPEN){ ! 47: u.u_error=ENODEV; ! 48: return; ! 49: } ! 50: if((p->reg=(struct omreg *)ubaddr(&omaddr[d]))==0 ! 51: || ubbadaddr(omaddr[d].ubno, (caddr_t)&p->reg->csr, sizeof(short))){ ! 52: printf("om%d absent\n", d); ! 53: u.u_error=ENODEV; ! 54: return; ! 55: } ! 56: p->flag|=OPEN; ! 57: if(omtiming==0) { ! 58: omtiming=1; ! 59: timeout(omtimeout, (caddr_t)0, OMTIMEOUT*HZ); ! 60: } ! 61: } ! 62: omclose(dev){ ! 63: om[minor(dev)].flag&=~OPEN; ! 64: } ! 65: omstrategy(bp) ! 66: struct buf *bp; ! 67: { ! 68: register d=minor(bp->b_dev), csr, pri; ! 69: register struct om *p=&om[d]; ! 70: register struct omreg *omreg; ! 71: register uaddr_t ubad; ! 72: if(bp->b_bcount&1){ ! 73: bp->b_flags|=B_ERROR; ! 74: iodone(bp); ! 75: return; ! 76: } ! 77: p->ubm=ubmbuf(omaddr[d].ubno, bp, UBDP|USLP); ! 78: ubad=ubadbuf(omaddr[d].ubno, bp, p->ubm); ! 79: pri=spl5(); ! 80: omreg=p->reg; ! 81: omreg->wc=-(bp->b_bcount>>1); ! 82: omreg->addr=ubad; ! 83: csr=IENABLE|xmem(ubad); ! 84: if(bp->b_flags&B_READ) csr|=READ; ! 85: omreg->csr=csr; ! 86: omreg->csr=csr|GO; ! 87: if ((bp->b_flags & B_READ) == 0) { ! 88: p->flag |= RUNNING; ! 89: splx(pri); ! 90: return; ! 91: } ! 92: /* ! 93: * reading: no timeout (might wait forever for mouse data) ! 94: * hence must allow signals ! 95: * hence do our own sleep ! 96: */ ! 97: p->flag |= (RUNNING|NOTIME); ! 98: if (tsleep((caddr_t)bp, PZERO+1, 0) != TS_OK) { ! 99: /* signal: tear down by hand */ ! 100: omreg->csr = ATTN|WAKEUP|IENABLE; ! 101: bp->b_flags |= B_ERROR; ! 102: ubmfree(omaddr[d].ubno, p->ubm); ! 103: iodone(bp); ! 104: p->flag &=~ (RUNNING|NOTIME|LATE); ! 105: } ! 106: splx(pri); ! 107: } ! 108: omread(dev){ ! 109: physio(omstrategy, &om[minor(dev)].buf, dev, B_READ, minphys); ! 110: } ! 111: omwrite(dev){ ! 112: physio(omstrategy, &om[minor(dev)].buf, dev, B_WRITE, minphys); ! 113: } ! 114: om0int(d){ ! 115: register struct buf *bp; ! 116: register struct om *p=&om[d]; ! 117: register struct omreg *omreg=p->reg; ! 118: register csr=omreg->csr; ! 119: if(p->flag&RUNNING && csr&(READY|ATTN)){ ! 120: omreg->csr=0; ! 121: bp=&p->buf; ! 122: if(csr&ERROR) ! 123: bp->b_flags|=B_ERROR; ! 124: bp->b_resid=(-omreg->wc)<<1; ! 125: ubmfree(omaddr[d].ubno, p->ubm); ! 126: iodone(bp); ! 127: p->flag&=~(RUNNING|NOTIME|LATE); ! 128: } ! 129: } ! 130: omtimeout(){ ! 131: register struct om *p, *ep; ! 132: register int s; ! 133: ep=&om[omcnt]; ! 134: s=spl5(); ! 135: for(p=&om[0];p!=ep;p++) if((p->flag&(RUNNING|NOTIME))==RUNNING){ ! 136: if((p->flag&LATE)==0) ! 137: p->flag|=LATE; ! 138: else { ! 139: p->reg->csr=ATTN|WAKEUP|IENABLE; ! 140: ubmfree(omaddr[p-om].ubno, p->ubm); ! 141: p->buf.b_flags|=B_ERROR; ! 142: iodone(&p->buf); ! 143: p->flag&=~(RUNNING|LATE); ! 144: } ! 145: } ! 146: splx(s); ! 147: timeout(omtimeout, (caddr_t)0, OMTIMEOUT*HZ); ! 148: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.