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