xref: /original-bsd/sys/hp300/dev/nhpib.c (revision 3705696b)
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.1 (Berkeley) 06/10/93
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 
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 
46 nhpibreset(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 
71 nhpibifc(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 
82 nhpibsend(unit, slave, sec, addr, origcnt)
83 	register char *addr;
84 {
85 	register struct hpib_softc *hs = &hpib_softc[unit];
86 	register struct nhpibdevice *hd;
87 	register int cnt = origcnt;
88 
89 	hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
90 	hd->hpib_acr = AUX_TCA;
91 	hd->hpib_data = C_UNL;
92 	if (nhpibwait(hd, MIS_BO))
93 		goto senderror;
94 	hd->hpib_data = C_TAG + hs->sc_ba;
95 	hd->hpib_acr = AUX_STON;
96 	if (nhpibwait(hd, MIS_BO))
97 		goto senderror;
98 	hd->hpib_data = C_LAG + slave;
99 	if (nhpibwait(hd, MIS_BO))
100 		goto senderror;
101 	if (sec != -1) {
102 		hd->hpib_data = C_SCG + sec;
103 		if (nhpibwait(hd, MIS_BO))
104 			goto senderror;
105 	}
106 	hd->hpib_acr = AUX_GTS;
107 	if (cnt) {
108 		while (--cnt > 0) {
109 			hd->hpib_data = *addr++;
110 			if (nhpibwait(hd, MIS_BO))
111 				goto senderror;
112 		}
113 		hd->hpib_acr = AUX_EOI;
114 		hd->hpib_data = *addr;
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
126 	}
127 	return(origcnt);
128 senderror:
129 	nhpibifc(hd);
130 	return(origcnt - cnt - 1);
131 }
132 
133 nhpibrecv(unit, slave, sec, addr, origcnt)
134 	register char *addr;
135 {
136 	register struct hpib_softc *hs = &hpib_softc[unit];
137 	register struct nhpibdevice *hd;
138 	register int cnt = origcnt;
139 
140 	hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
141 	hd->hpib_acr = AUX_TCA;
142 	hd->hpib_data = C_UNL;
143 	if (nhpibwait(hd, MIS_BO))
144 		goto recverror;
145 	hd->hpib_data = C_LAG + hs->sc_ba;
146 	hd->hpib_acr = AUX_SLON;
147 	if (nhpibwait(hd, MIS_BO))
148 		goto recverror;
149 	hd->hpib_data = C_TAG + slave;
150 	if (nhpibwait(hd, MIS_BO))
151 		goto recverror;
152 	if (sec != -1) {
153 		hd->hpib_data = C_SCG + sec;
154 		if (nhpibwait(hd, MIS_BO))
155 			goto recverror;
156 	}
157 	hd->hpib_acr = AUX_RHDF;
158 	hd->hpib_acr = AUX_GTS;
159 	if (cnt) {
160 		while (--cnt >= 0) {
161 			if (nhpibwait(hd, MIS_BI))
162 				goto recvbyteserror;
163 			*addr++ = hd->hpib_data;
164 		}
165 		hd->hpib_acr = AUX_TCA;
166 		hd->hpib_data = (slave == 31) ? C_UNA : C_UNT;
167 		(void) nhpibwait(hd, MIS_BO);
168 	}
169 	return(origcnt);
170 recverror:
171 	nhpibifc(hd);
172 recvbyteserror:
173 	return(origcnt - cnt - 1);
174 }
175 
176 nhpibgo(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;
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;
207 		}
208 		hs->sc_curcnt = --count;
209 		dmago(hs->sc_dq.dq_ctlr, addr, count, DMAGO_BYTE);
210 		nhpibsend(unit, slave, sec, 0, 0);
211 	}
212 	hd->hpib_ie = IDS_IE | IDS_DMA(hs->sc_dq.dq_ctlr);
213 }
214 
215 nhpibdone(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;
226 	hs->sc_flags |= HPIBF_DONE;
227 	hd->hpib_ie = IDS_IE;
228 	if ((hs->sc_flags & HPIBF_READ) == 0) {
229 		if (hs->sc_count == 1) {
230 			(void) nhpibwait(hd, MIS_BO);
231 			hd->hpib_acr = AUX_EOI;
232 			hd->hpib_data = *hs->sc_addr;
233 			hd->hpib_mim = MIS_BO;
234 		}
235 #ifdef DEBUG
236 		else if (hs->sc_count)
237 			panic("nhpibdone");
238 #endif
239 	}
240 }
241 
242 nhpibintr(unit)
243 	register int unit;
244 {
245 	register struct hpib_softc *hs = &hpib_softc[unit];
246 	register struct nhpibdevice *hd;
247 	register struct devqueue *dq;
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;
259 	dq = hs->sc_sq.dq_forw;
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);
268 	} else if (hs->sc_flags & HPIBF_PPOLL) {
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 		}
275 #ifdef DEBUG
276 		else
277 			printf("hpib%d: PPOLL intr bad status %x\n",
278 			       unit, stat0);
279 #endif
280 	}
281 	return(1);
282 }
283 
284 nhpibppoll(unit)
285 	int unit;
286 {
287 	register struct nhpibdevice *hd;
288 	register int ppoll;
289 
290 	hd = (struct nhpibdevice *)hpib_softc[unit].sc_hc->hp_addr;
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 
298 nhpibwait(hd, x)
299 	register struct nhpibdevice *hd;
300 {
301 	register int timo = hpibtimeout;
302 
303 	while ((hd->hpib_mis & x) == 0 && --timo)
304 		DELAY(1);
305 	if (timo == 0)
306 		return(-1);
307 	return(0);
308 }
309 
310 void
311 nhpibppwatch(arg)
312 	void *arg;
313 {
314 	register struct hpib_softc *hs;
315 	register int unit;
316 	extern int cold;
317 
318 	unit = (int)arg;
319 	hs = &hpib_softc[unit];
320 	if ((hs->sc_flags & HPIBF_PPOLL) == 0)
321 		return;
322 again:
323 	if (nhpibppoll(unit) & (0x80 >> hs->sc_sq.dq_forw->dq_slave))
324        		((struct nhpibdevice *)hs->sc_hc->hp_addr)->hpib_mim = MIS_BO;
325 	else if (cold)
326 		/* timeouts not working yet */
327 		goto again;
328 	else
329 		timeout(nhpibppwatch, (void *)unit, 1);
330 }
331 #endif
332