|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)ct.c 7.1 (Berkeley) 6/5/86 ! 7: */ ! 8: ! 9: #include "ct.h" ! 10: #if NCT > 0 ! 11: /* ! 12: * GP DR11C driver used for C/A/T or Autologic APS micro-5 ! 13: */ ! 14: #include "../machine/pte.h" ! 15: ! 16: #include "param.h" ! 17: #include "systm.h" ! 18: #include "ioctl.h" ! 19: #include "tty.h" ! 20: #include "map.h" ! 21: #include "buf.h" ! 22: #include "conf.h" ! 23: #include "dir.h" ! 24: #include "user.h" ! 25: #include "kernel.h" ! 26: ! 27: #include "ubareg.h" ! 28: #include "ubavar.h" ! 29: ! 30: #define PCAT (PZERO+9) ! 31: #define CATHIWAT 100 ! 32: #define CATLOWAT 30 ! 33: ! 34: #define REQUEST_B 0x8000 ! 35: #define REQUEST_A 0x80 ! 36: #define INT_ENB_A 0x40 ! 37: #define INT_ENB_B 0x20 ! 38: #define CSR1 0x2 ! 39: #define CSR0 0x1 ! 40: ! 41: struct ct_softc { ! 42: int sc_state; ! 43: struct clist sc_oq; ! 44: } ct_softc[NCT]; ! 45: ! 46: #define CT_OPEN 0x1 ! 47: #define CT_RUNNING 0x2 ! 48: ! 49: struct ctdevice { ! 50: u_short ctcsr; ! 51: u_short ctobuf; ! 52: u_short ctibuf; ! 53: }; ! 54: ! 55: int ctprobe(), ctattach(), ctintr(); ! 56: struct uba_device *ctdinfo[NCT]; ! 57: u_short ctstd[] = { 0167770, 0 }; ! 58: struct uba_driver ctdriver = ! 59: { ctprobe, 0, ctattach, 0, ctstd, "ct", ctdinfo }; ! 60: ! 61: #define CTUNIT(dev) (minor(dev)) ! 62: ! 63: int ct_init = 0; /* set to CSR1 for testing loopback on controller */ ! 64: ! 65: ctprobe(reg) ! 66: caddr_t reg; ! 67: { ! 68: register int br, cvec; /* value-result */ ! 69: register struct ctdevice *ctaddr = (struct ctdevice *)reg; ! 70: ! 71: #ifdef lint ! 72: br = 0; cvec = br; br = cvec; ! 73: ctintr(0); ! 74: #endif ! 75: /* ! 76: * There is no way to make a DR11c interrupt without some ! 77: * external support. We can't always trust that the typesetter ! 78: * will be online and ready so we've made other provisions. ! 79: * This probe assumes setting the B Int Enb will generate ! 80: * an interrupt. To do this, we set CSR0 and loop this back ! 81: * to REQUEST_B in the second plug on the controller. ! 82: * Then, we reset the vector to be that for the "real" device. ! 83: */ ! 84: ctaddr->ctcsr = INT_ENB_B | CSR0; /* Assume hardware loopback! */ ! 85: DELAY(1000); ! 86: ctaddr->ctcsr = ct_init; /* should be CSR1 for loopback testing */ ! 87: if (cvec & 04) { ! 88: printf("ct: resetting vector %o to %o\n", cvec, cvec&0773); ! 89: cvec &= 0773; ! 90: } ! 91: return (sizeof (struct ctdevice)); ! 92: } ! 93: ! 94: /*ARGSUSED*/ ! 95: ctattach(ui) ! 96: struct uba_device *ui; ! 97: { ! 98: } ! 99: ! 100: ctopen(dev) ! 101: dev_t dev; ! 102: { ! 103: register struct ct_softc *sc; ! 104: register struct uba_device *ui; ! 105: register struct ctdevice *ctaddr; ! 106: ! 107: if (CTUNIT(dev) >= NCT || (ui = ctdinfo[CTUNIT(dev)]) == 0 || ! 108: ui->ui_alive == 0) ! 109: return (ENODEV); ! 110: if ((sc = &ct_softc[CTUNIT(dev)])->sc_state&CT_OPEN) ! 111: return (EBUSY); ! 112: sc->sc_state = CT_OPEN; ! 113: ctaddr = (struct ctdevice *)ui->ui_addr; ! 114: ctaddr->ctcsr |= INT_ENB_A; ! 115: return (0); ! 116: } ! 117: ! 118: ctclose(dev) ! 119: dev_t dev; ! 120: { ! 121: ct_softc[CTUNIT(dev)].sc_state = 0; ! 122: ctintr(dev); ! 123: return (0); ! 124: } ! 125: ! 126: ctwrite(dev, uio) ! 127: dev_t dev; ! 128: struct uio *uio; ! 129: { ! 130: register struct ct_softc *sc = &ct_softc[CTUNIT(dev)]; ! 131: register int c; ! 132: int s; ! 133: ! 134: while ((c = uwritec(uio)) >= 0) { ! 135: s = spl5(); ! 136: while (sc->sc_oq.c_cc > CATHIWAT) ! 137: sleep((caddr_t)&sc->sc_oq, PCAT); ! 138: while (putc(c, &sc->sc_oq) < 0) ! 139: sleep((caddr_t)&lbolt, PCAT); ! 140: if ( ! (sc->sc_state & CT_RUNNING) ) ! 141: ctintr(dev); ! 142: splx(s); ! 143: } ! 144: return (0); ! 145: } ! 146: ! 147: /* ! 148: * The C/A/T is usually wired to accept data on the .5us DATA_AVAIL strobe. ! 149: * If you use this with a C/A/T you can remove the lines with "APSu5" below. ! 150: * This is way out of spec for the Autologic APS micro-5 which requires ! 151: * at least a 40 microsec strobe. We therefore use CSR1 output as the ! 152: * "strobe". It is set after data is loaded and reset only in the ! 153: * interrupt routine. Therefore, the "strobe" is high for adequate time. ! 154: * The constant "ctdelay" determines the "low" time for the strobe ! 155: * and may have to be larger on a 780. "2" gives about 10us on a 750. ! 156: */ ! 157: int ctdelay = 2; /* here so it's visible & changeable */ ! 158: ! 159: ctintr(dev) ! 160: dev_t dev; ! 161: { ! 162: register int c; ! 163: register struct ct_softc *sc = &ct_softc[CTUNIT(dev)]; ! 164: register struct ctdevice *ctaddr = ! 165: (struct ctdevice *)ctdinfo[CTUNIT(dev)]->ui_addr; ! 166: ! 167: if ((ctaddr->ctcsr&(INT_ENB_B|REQUEST_B)) == (INT_ENB_B|REQUEST_B)) { ! 168: ctaddr->ctcsr &= ~(CSR0 | INT_ENB_B); /* set in ctprobe */ ! 169: } ! 170: if ((ctaddr->ctcsr&(INT_ENB_A|REQUEST_A)) == (INT_ENB_A|REQUEST_A)) { ! 171: if ((c = getc(&sc->sc_oq)) >= 0) { ! 172: ctaddr->ctcsr &= ~CSR1; /* APSu5 - drop strobe */ ! 173: ctaddr->ctobuf = c; ! 174: DELAY(ctdelay); /* APSu5 - pause a bit */ ! 175: ctaddr->ctcsr |= CSR1; /* APSu5 - raise strobe */ ! 176: sc->sc_state |= CT_RUNNING; ! 177: if (sc->sc_oq.c_cc==0 || sc->sc_oq.c_cc==CATLOWAT) ! 178: wakeup((caddr_t)&sc->sc_oq); ! 179: } else if (sc->sc_state == 0) { ! 180: ctaddr->ctcsr = 0; ! 181: } else ! 182: sc->sc_state &= ~CT_RUNNING; ! 183: } ! 184: } ! 185: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.