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