|
|
1.1 ! root 1: /* ! 2: * DR11C for Mergenthaler 202 ! 3: */ ! 4: #include "sys/param.h" ! 5: #include "sys/conf.h" ! 6: #include "sys/stream.h" ! 7: #include "sys/ubaddr.h" ! 8: #include "sys/mg.h" ! 9: ! 10: /* ! 11: * hardware ! 12: */ ! 13: struct device { ! 14: u_short csr; ! 15: u_short wbuf; ! 16: u_short rbuf; ! 17: }; ! 18: ! 19: #define CSR0 1 ! 20: #define CSR1 2 ! 21: #define REQA 0200 ! 22: #define REQB 0100000 ! 23: #define INTA 0100 ! 24: #define INTB 040 ! 25: ! 26: /* ! 27: * stream glue ! 28: */ ! 29: long mgopen(); ! 30: int nodev(), mgclose(), mgoput(); ! 31: ! 32: static struct qinit mgrinit = { ! 33: nodev, NULL, mgopen, mgclose, 0, 0 ! 34: }; ! 35: static struct qinit mgwinit = { ! 36: mgoput, NULL, mgopen, mgclose, 200, 100 ! 37: }; ! 38: struct streamtab mginfo = { ! 39: &mgrinit, &mgwinit ! 40: }; ! 41: ! 42: /* ! 43: * config glue ! 44: */ ! 45: extern struct mg mg[]; /* one per device */ ! 46: extern struct ubaddr mgaddr[]; /* one per device */ ! 47: extern int mgcnt; /* one per device or what? */ ! 48: struct cdevsw mgcdev = cstrinit(&mginfo); ! 49: ! 50: long ! 51: mgopen(q, d) ! 52: register struct queue *q; ! 53: { ! 54: register struct mg *mp; ! 55: register dev, s; ! 56: ! 57: if((dev = (minor(d) >> 1)) >= mgcnt) ! 58: return 0; ! 59: mp = &mg[dev]; ! 60: if((mp->addr = (struct device *)ubaddr(&mgaddr[dev])) == 0 ! 61: || ubbadaddr(mgaddr[dev].ubno, mp->addr, sizeof(u_short))) { ! 62: printf("mg%d absent\n", d); ! 63: return 0; ! 64: } ! 65: mp->addr->csr |= CSR0 | CSR1; ! 66: if(d & 01) { ! 67: if(mp->wq != NULL) ! 68: return 0; ! 69: mp->addr->csr |= INTA; ! 70: mp->wq = WR(q); ! 71: } ! 72: else { ! 73: if(mp->rq != NULL) ! 74: return 0; ! 75: s = mp->addr->rbuf; ! 76: mp->addr->csr |= INTB; ! 77: mp->rq = q; ! 78: } ! 79: WR(q)->ptr = q->ptr = (caddr_t) minor(d); ! 80: return 1; ! 81: } ! 82: ! 83: mgclose(q) ! 84: register struct queue *q; ! 85: { ! 86: register struct mg *mp = &mg[((int)q->ptr) >> 1]; ! 87: ! 88: if(((int)q->ptr) & 01) { ! 89: mp->wq = NULL; ! 90: } ! 91: else { ! 92: mp->addr->csr &= (~INTB); ! 93: flushq(WR(q), 1); ! 94: mp->rq = NULL; ! 95: } ! 96: } ! 97: ! 98: mg1int(dev) ! 99: { ! 100: register struct mg *mp = &mg[dev]; ! 101: register c; ! 102: ! 103: c = mp->addr->rbuf; ! 104: if(mp->rq && (mp->rq->flag & QFULL) == 0) ! 105: putd(mp->rq->next->qinfo->putp, mp->rq->next, c); ! 106: } ! 107: ! 108: mg0int(dev) ! 109: { ! 110: register struct mg *mp = &mg[dev]; ! 111: ! 112: mp->busy = 0; ! 113: mgstart(mp); ! 114: } ! 115: ! 116: mgoput(q, bp) ! 117: register struct queue *q; ! 118: register struct block *bp; ! 119: { ! 120: switch(bp->type) { ! 121: ! 122: case M_IOCTL: ! 123: bp->type = M_IOCNAK; ! 124: bp->wptr = bp->rptr; ! 125: qreply(q, bp); ! 126: return; ! 127: ! 128: case M_FLUSH: ! 129: flushq(q, 0); ! 130: break; ! 131: ! 132: case M_DATA: ! 133: putq(q, bp); ! 134: mgstart(&mg[((int)q->ptr) >> 1]); ! 135: return; ! 136: ! 137: default: ! 138: break; ! 139: } ! 140: freeb(bp); ! 141: } ! 142: ! 143: mgstart(mp) ! 144: register struct mg *mp; ! 145: { ! 146: register struct block *bp; ! 147: register s; ! 148: ! 149: if(mp->wq == NULL) ! 150: return; ! 151: s = spl6(); ! 152: if((mp->busy == 0) && mp->wq->count) { ! 153: bp = getq(mp->wq); ! 154: switch(bp->type) { ! 155: ! 156: case M_DATA: ! 157: mp->addr->wbuf = *bp->rptr++; ! 158: mp->busy = 1; ! 159: if(bp->rptr >= bp->wptr) ! 160: freeb(bp); ! 161: else ! 162: putbq(mp->wq, bp); ! 163: break; ! 164: ! 165: default: ! 166: freeb(bp); ! 167: break; ! 168: } ! 169: } ! 170: splx(s); ! 171: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.