date and time created 94/01/05 12:54:31 by pendry
[unix-history] / usr / src / sys / hp300 / dev / nhpib.c
CommitLineData
60f56dfc 1/*
030a8056
KB
2 * Copyright (c) 1982, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
60f56dfc
KM
4 *
5 * %sccs.include.redist.c%
6 *
030a8056 7 * @(#)nhpib.c 8.1 (Berkeley) %G%
60f56dfc
KM
8 */
9
10/*
11 * Internal/98624 HPIB driver
12 */
13#include "hpib.h"
14#if NHPIB > 0
15
38a01dbe
KB
16#include <sys/param.h>
17#include <sys/systm.h>
18#include <sys/buf.h>
b28b3a13 19
38a01dbe
KB
20#include <hp/dev/device.h>
21#include <hp300/dev/nhpibreg.h>
22#include <hp300/dev/hpibvar.h>
23#include <hp300/dev/dmavar.h>
60f56dfc
KM
24
25nhpibtype(hc)
26 register struct hp_ctlr *hc;
27{
28 register struct hpib_softc *hs = &hpib_softc[hc->hp_unit];
29 register struct nhpibdevice *hd = (struct nhpibdevice *)hc->hp_addr;
30
7a5fd5d5 31 if (hc->hp_addr == internalhpib) {
60f56dfc
KM
32 hs->sc_type = HPIBA;
33 hs->sc_ba = HPIBA_BA;
34 hc->hp_ipl = HPIBA_IPL;
35 }
36 else if (hd->hpib_cid == HPIBB) {
37 hs->sc_type = HPIBB;
38 hs->sc_ba = hd->hpib_csa & CSA_BA;
39 hc->hp_ipl = HPIB_IPL(hd->hpib_ids);
40 }
41 else
42 return(0);
43 return(1);
44}
45
46nhpibreset(unit)
47{
48 register struct hpib_softc *hs = &hpib_softc[unit];
49 register struct nhpibdevice *hd;
50
51 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
52 hd->hpib_acr = AUX_SSWRST;
53 hd->hpib_ar = hs->sc_ba;
54 hd->hpib_lim = LIS_ERR;
55 hd->hpib_mim = 0;
56 hd->hpib_acr = AUX_CDAI;
57 hd->hpib_acr = AUX_CSHDW;
58 hd->hpib_acr = AUX_SSTD1;
59 hd->hpib_acr = AUX_SVSTD1;
60 hd->hpib_acr = AUX_CPP;
61 hd->hpib_acr = AUX_CHDFA;
62 hd->hpib_acr = AUX_CHDFE;
63 hd->hpib_acr = AUX_RHDF;
64 hd->hpib_acr = AUX_CSWRST;
65 nhpibifc(hd);
66 hd->hpib_ie = IDS_IE;
67 hd->hpib_data = C_DCL;
68 DELAY(100000);
69}
70
71nhpibifc(hd)
72 register struct nhpibdevice *hd;
73{
74 hd->hpib_acr = AUX_TCA;
75 hd->hpib_acr = AUX_CSRE;
76 hd->hpib_acr = AUX_SSIC;
77 DELAY(100);
78 hd->hpib_acr = AUX_CSIC;
79 hd->hpib_acr = AUX_SSRE;
80}
81
a47d912d 82nhpibsend(unit, slave, sec, addr, origcnt)
60f56dfc 83 register char *addr;
60f56dfc
KM
84{
85 register struct hpib_softc *hs = &hpib_softc[unit];
86 register struct nhpibdevice *hd;
a47d912d 87 register int cnt = origcnt;
60f56dfc
KM
88
89 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
90 hd->hpib_acr = AUX_TCA;
91 hd->hpib_data = C_UNL;
a47d912d
KM
92 if (nhpibwait(hd, MIS_BO))
93 goto senderror;
60f56dfc
KM
94 hd->hpib_data = C_TAG + hs->sc_ba;
95 hd->hpib_acr = AUX_STON;
a47d912d
KM
96 if (nhpibwait(hd, MIS_BO))
97 goto senderror;
60f56dfc 98 hd->hpib_data = C_LAG + slave;
a47d912d
KM
99 if (nhpibwait(hd, MIS_BO))
100 goto senderror;
60f56dfc
KM
101 if (sec != -1) {
102 hd->hpib_data = C_SCG + sec;
a47d912d
KM
103 if (nhpibwait(hd, MIS_BO))
104 goto senderror;
60f56dfc
KM
105 }
106 hd->hpib_acr = AUX_GTS;
107 if (cnt) {
a47d912d 108 while (--cnt > 0) {
60f56dfc 109 hd->hpib_data = *addr++;
a47d912d
KM
110 if (nhpibwait(hd, MIS_BO))
111 goto senderror;
60f56dfc
KM
112 }
113 hd->hpib_acr = AUX_EOI;
114 hd->hpib_data = *addr;
a47d912d
KM
115 if (nhpibwait(hd, MIS_BO))
116 goto senderror;
117 hd->hpib_acr = AUX_TCA;
118#if 0
119 /*
120 * May be causing 345 disks to hang due to interference
121 * with PPOLL mechanism.
122 */
123 hd->hpib_data = C_UNL;
124 (void) nhpibwait(hd, MIS_BO);
125#endif
60f56dfc 126 }
a47d912d
KM
127 return(origcnt);
128senderror:
129 nhpibifc(hd);
130 return(origcnt - cnt - 1);
60f56dfc
KM
131}
132
a47d912d 133nhpibrecv(unit, slave, sec, addr, origcnt)
60f56dfc 134 register char *addr;
60f56dfc
KM
135{
136 register struct hpib_softc *hs = &hpib_softc[unit];
137 register struct nhpibdevice *hd;
a47d912d 138 register int cnt = origcnt;
60f56dfc
KM
139
140 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
141 hd->hpib_acr = AUX_TCA;
142 hd->hpib_data = C_UNL;
a47d912d
KM
143 if (nhpibwait(hd, MIS_BO))
144 goto recverror;
60f56dfc
KM
145 hd->hpib_data = C_LAG + hs->sc_ba;
146 hd->hpib_acr = AUX_SLON;
a47d912d
KM
147 if (nhpibwait(hd, MIS_BO))
148 goto recverror;
60f56dfc 149 hd->hpib_data = C_TAG + slave;
a47d912d
KM
150 if (nhpibwait(hd, MIS_BO))
151 goto recverror;
60f56dfc
KM
152 if (sec != -1) {
153 hd->hpib_data = C_SCG + sec;
a47d912d
KM
154 if (nhpibwait(hd, MIS_BO))
155 goto recverror;
60f56dfc
KM
156 }
157 hd->hpib_acr = AUX_RHDF;
158 hd->hpib_acr = AUX_GTS;
159 if (cnt) {
160 while (--cnt >= 0) {
a47d912d
KM
161 if (nhpibwait(hd, MIS_BI))
162 goto recvbyteserror;
60f56dfc
KM
163 *addr++ = hd->hpib_data;
164 }
60f56dfc 165 hd->hpib_acr = AUX_TCA;
a47d912d
KM
166 hd->hpib_data = (slave == 31) ? C_UNA : C_UNT;
167 (void) nhpibwait(hd, MIS_BO);
60f56dfc 168 }
a47d912d
KM
169 return(origcnt);
170recverror:
171 nhpibifc(hd);
172recvbyteserror:
173 return(origcnt - cnt - 1);
60f56dfc
KM
174}
175
176nhpibgo(unit, slave, sec, addr, count, rw)
177 register int unit, slave;
178 char *addr;
179{
180 register struct hpib_softc *hs = &hpib_softc[unit];
181 register struct nhpibdevice *hd;
182
183 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
184 hs->sc_flags |= HPIBF_IO;
185 if (rw == B_READ)
186 hs->sc_flags |= HPIBF_READ;
187#ifdef DEBUG
188 else if (hs->sc_flags & HPIBF_READ) {
189 printf("nhpibgo: HPIBF_READ still set\n");
190 hs->sc_flags &= ~HPIBF_READ;
191 }
192#endif
193 hs->sc_count = count;
194 hs->sc_addr = addr;
195 if (hs->sc_flags & HPIBF_READ) {
196 hs->sc_curcnt = count;
197 dmago(hs->sc_dq.dq_ctlr, addr, count, DMAGO_BYTE|DMAGO_READ);
198 nhpibrecv(unit, slave, sec, 0, 0);
199 hd->hpib_mim = MIS_END;
a47d912d
KM
200 } else {
201 hd->hpib_mim = 0;
202 if (count < hpibdmathresh) {
203 hs->sc_curcnt = count;
204 nhpibsend(unit, slave, sec, addr, count);
205 nhpibdone(unit);
206 return;
60f56dfc 207 }
a47d912d
KM
208 hs->sc_curcnt = --count;
209 dmago(hs->sc_dq.dq_ctlr, addr, count, DMAGO_BYTE);
210 nhpibsend(unit, slave, sec, 0, 0);
60f56dfc
KM
211 }
212 hd->hpib_ie = IDS_IE | IDS_DMA(hs->sc_dq.dq_ctlr);
213}
214
215nhpibdone(unit)
216 register int unit;
217{
218 register struct hpib_softc *hs = &hpib_softc[unit];
219 register struct nhpibdevice *hd;
220 register int cnt;
221
222 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
223 cnt = hs->sc_curcnt;
224 hs->sc_addr += cnt;
225 hs->sc_count -= cnt;
a47d912d
KM
226 hs->sc_flags |= HPIBF_DONE;
227 hd->hpib_ie = IDS_IE;
228 if ((hs->sc_flags & HPIBF_READ) == 0) {
60f56dfc 229 if (hs->sc_count == 1) {
a47d912d 230 (void) nhpibwait(hd, MIS_BO);
60f56dfc 231 hd->hpib_acr = AUX_EOI;
a47d912d
KM
232 hd->hpib_data = *hs->sc_addr;
233 hd->hpib_mim = MIS_BO;
60f56dfc 234 }
a47d912d
KM
235#ifdef DEBUG
236 else if (hs->sc_count)
237 panic("nhpibdone");
238#endif
60f56dfc
KM
239 }
240}
241
242nhpibintr(unit)
243 register int unit;
244{
245 register struct hpib_softc *hs = &hpib_softc[unit];
246 register struct nhpibdevice *hd;
a47d912d 247 register struct devqueue *dq;
60f56dfc
KM
248 register int stat0;
249 int stat1;
250
251#ifdef lint
252 if (stat1 = unit) return(1);
253#endif
254 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
255 if ((hd->hpib_ids & IDS_IR) == 0)
256 return(0);
257 stat0 = hd->hpib_mis;
258 stat1 = hd->hpib_lis;
a47d912d 259 dq = hs->sc_sq.dq_forw;
60f56dfc
KM
260 if (hs->sc_flags & HPIBF_IO) {
261 hd->hpib_mim = 0;
262 if ((hs->sc_flags & HPIBF_DONE) == 0)
263 dmastop(hs->sc_dq.dq_ctlr);
264 hd->hpib_acr = AUX_TCA;
265 hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ);
266 dmafree(&hs->sc_dq);
267 (dq->dq_driver->d_intr)(dq->dq_unit);
a47d912d 268 } else if (hs->sc_flags & HPIBF_PPOLL) {
60f56dfc
KM
269 hd->hpib_mim = 0;
270 stat0 = nhpibppoll(unit);
271 if (stat0 & (0x80 >> dq->dq_slave)) {
272 hs->sc_flags &= ~HPIBF_PPOLL;
273 (dq->dq_driver->d_intr)(dq->dq_unit);
274 }
a47d912d
KM
275#ifdef DEBUG
276 else
277 printf("hpib%d: PPOLL intr bad status %x\n",
278 unit, stat0);
279#endif
60f56dfc
KM
280 }
281 return(1);
282}
283
284nhpibppoll(unit)
a47d912d 285 int unit;
60f56dfc 286{
60f56dfc
KM
287 register struct nhpibdevice *hd;
288 register int ppoll;
289
a47d912d 290 hd = (struct nhpibdevice *)hpib_softc[unit].sc_hc->hp_addr;
60f56dfc
KM
291 hd->hpib_acr = AUX_SPP;
292 DELAY(25);
293 ppoll = hd->hpib_cpt;
294 hd->hpib_acr = AUX_CPP;
295 return(ppoll);
296}
297
a47d912d 298nhpibwait(hd, x)
60f56dfc
KM
299 register struct nhpibdevice *hd;
300{
60f56dfc
KM
301 register int timo = hpibtimeout;
302
a47d912d
KM
303 while ((hd->hpib_mis & x) == 0 && --timo)
304 DELAY(1);
60f56dfc
KM
305 if (timo == 0)
306 return(-1);
307 return(0);
308}
309
88a0c57a
CT
310void
311nhpibppwatch(arg)
312 void *arg;
60f56dfc 313{
88a0c57a
CT
314 register struct hpib_softc *hs;
315 register int unit;
d1a1d388 316 extern int cold;
60f56dfc 317
88a0c57a
CT
318 unit = (int)arg;
319 hs = &hpib_softc[unit];
60f56dfc
KM
320 if ((hs->sc_flags & HPIBF_PPOLL) == 0)
321 return;
d1a1d388 322again:
a47d912d 323 if (nhpibppoll(unit) & (0x80 >> hs->sc_sq.dq_forw->dq_slave))
60f56dfc 324 ((struct nhpibdevice *)hs->sc_hc->hp_addr)->hpib_mim = MIS_BO;
d1a1d388
MH
325 else if (cold)
326 /* timeouts not working yet */
327 goto again;
60f56dfc 328 else
88a0c57a 329 timeout(nhpibppwatch, (void *)unit, 1);
60f56dfc
KM
330}
331#endif