4.3BSD release version
[unix-history] / usr / src / sys / vax / uba / ct.c
CommitLineData
da7c5cc6 1/*
0880b18e 2 * Copyright (c) 1982, 1986 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
0880b18e 6 * @(#)ct.c 7.1 (Berkeley) %G%
da7c5cc6 7 */
99aa0ab4 8
a53c8506 9#include "ct.h"
99aa0ab4
BJ
10#if NCT > 0
11/*
ba80d2df 12 * GP DR11C driver used for C/A/T or Autologic APS micro-5
99aa0ab4 13 */
961945a8 14#include "../machine/pte.h"
99aa0ab4 15
ff360633
JB
16#include "param.h"
17#include "systm.h"
f88025a6 18#include "ioctl.h"
ff360633
JB
19#include "tty.h"
20#include "map.h"
21#include "buf.h"
22#include "conf.h"
23#include "dir.h"
24#include "user.h"
ba80d2df 25#include "kernel.h"
99aa0ab4 26
ff360633
JB
27#include "ubareg.h"
28#include "ubavar.h"
896962b1 29
99aa0ab4
BJ
30#define PCAT (PZERO+9)
31#define CATHIWAT 100
32#define CATLOWAT 30
33
ba80d2df
MK
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
a53c8506 41struct ct_softc {
ba80d2df 42 int sc_state;
a53c8506
BJ
43 struct clist sc_oq;
44} ct_softc[NCT];
99aa0ab4 45
ba80d2df
MK
46#define CT_OPEN 0x1
47#define CT_RUNNING 0x2
48
a53c8506 49struct ctdevice {
ba80d2df
MK
50 u_short ctcsr;
51 u_short ctobuf;
52 u_short ctibuf;
99aa0ab4
BJ
53};
54
a53c8506
BJ
55int ctprobe(), ctattach(), ctintr();
56struct uba_device *ctdinfo[NCT];
ba80d2df 57u_short ctstd[] = { 0167770, 0 };
a53c8506
BJ
58struct uba_driver ctdriver =
59 { ctprobe, 0, ctattach, 0, ctstd, "ct", ctdinfo };
60
042f22be
BJ
61#define CTUNIT(dev) (minor(dev))
62
ba80d2df
MK
63int ct_init = 0; /* set to CSR1 for testing loopback on controller */
64
a53c8506
BJ
65ctprobe(reg)
66 caddr_t reg;
67{
2b50de22 68 register int br, cvec; /* value-result */
a53c8506
BJ
69 register struct ctdevice *ctaddr = (struct ctdevice *)reg;
70
89b8a44c
BJ
71#ifdef lint
72 br = 0; cvec = br; br = cvec;
73 ctintr(0);
74#endif
ba80d2df
MK
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 }
9c0adba0 91 return (sizeof (struct ctdevice));
a53c8506 92}
99aa0ab4 93
042f22be
BJ
94/*ARGSUSED*/
95ctattach(ui)
58bca61d 96 struct uba_device *ui;
042f22be 97{
042f22be
BJ
98}
99
99aa0ab4 100ctopen(dev)
a53c8506 101 dev_t dev;
99aa0ab4 102{
a53c8506
BJ
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 ||
ba80d2df
MK
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;
7da157da 115 return (0);
99aa0ab4
BJ
116}
117
a53c8506
BJ
118ctclose(dev)
119 dev_t dev;
99aa0ab4 120{
ba80d2df 121 ct_softc[CTUNIT(dev)].sc_state = 0;
a53c8506 122 ctintr(dev);
ba80d2df 123 return (0);
99aa0ab4
BJ
124}
125
406ddcbe 126ctwrite(dev, uio)
a53c8506 127 dev_t dev;
406ddcbe 128 struct uio *uio;
99aa0ab4 129{
a53c8506
BJ
130 register struct ct_softc *sc = &ct_softc[CTUNIT(dev)];
131 register int c;
ba80d2df 132 int s;
99aa0ab4 133
ba80d2df
MK
134 while ((c = uwritec(uio)) >= 0) {
135 s = spl5();
a53c8506
BJ
136 while (sc->sc_oq.c_cc > CATHIWAT)
137 sleep((caddr_t)&sc->sc_oq, PCAT);
138 while (putc(c, &sc->sc_oq) < 0)
99aa0ab4 139 sleep((caddr_t)&lbolt, PCAT);
ba80d2df
MK
140 if ( ! (sc->sc_state & CT_RUNNING) )
141 ctintr(dev);
142 splx(s);
99aa0ab4 143 }
ba80d2df 144 return (0);
99aa0ab4
BJ
145}
146
ba80d2df
MK
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 */
157int ctdelay = 2; /* here so it's visible & changeable */
158
a53c8506
BJ
159ctintr(dev)
160 dev_t dev;
99aa0ab4
BJ
161{
162 register int c;
a53c8506
BJ
163 register struct ct_softc *sc = &ct_softc[CTUNIT(dev)];
164 register struct ctdevice *ctaddr =
165 (struct ctdevice *)ctdinfo[CTUNIT(dev)]->ui_addr;
99aa0ab4 166
ba80d2df
MK
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)) {
a53c8506 171 if ((c = getc(&sc->sc_oq)) >= 0) {
ba80d2df
MK
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;
a53c8506 177 if (sc->sc_oq.c_cc==0 || sc->sc_oq.c_cc==CATLOWAT)
58bca61d 178 wakeup((caddr_t)&sc->sc_oq);
ba80d2df 179 } else if (sc->sc_state == 0) {
a53c8506 180 ctaddr->ctcsr = 0;
ba80d2df
MK
181 } else
182 sc->sc_state &= ~CT_RUNNING;
99aa0ab4 183 }
99aa0ab4
BJ
184}
185#endif