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