nhpib.c revision 1.15 1 1.15 scottr /* $NetBSD: nhpib.c,v 1.15 1997/03/31 07:37:30 scottr Exp $ */
2 1.5 cgd
3 1.1 cgd /*
4 1.14 thorpej * Copyright (c) 1996, 1997 Jason R. Thorpe. All rights reserved.
5 1.4 mycroft * Copyright (c) 1982, 1990, 1993
6 1.4 mycroft * The Regents of the University of California. All rights reserved.
7 1.1 cgd *
8 1.1 cgd * Redistribution and use in source and binary forms, with or without
9 1.1 cgd * modification, are permitted provided that the following conditions
10 1.1 cgd * are met:
11 1.1 cgd * 1. Redistributions of source code must retain the above copyright
12 1.1 cgd * notice, this list of conditions and the following disclaimer.
13 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
14 1.1 cgd * notice, this list of conditions and the following disclaimer in the
15 1.1 cgd * documentation and/or other materials provided with the distribution.
16 1.1 cgd * 3. All advertising materials mentioning features or use of this software
17 1.1 cgd * must display the following acknowledgement:
18 1.1 cgd * This product includes software developed by the University of
19 1.1 cgd * California, Berkeley and its contributors.
20 1.1 cgd * 4. Neither the name of the University nor the names of its contributors
21 1.1 cgd * may be used to endorse or promote products derived from this software
22 1.1 cgd * without specific prior written permission.
23 1.1 cgd *
24 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 1.1 cgd * SUCH DAMAGE.
35 1.1 cgd *
36 1.5 cgd * @(#)nhpib.c 8.2 (Berkeley) 1/12/94
37 1.1 cgd */
38 1.1 cgd
39 1.1 cgd /*
40 1.1 cgd * Internal/98624 HPIB driver
41 1.1 cgd */
42 1.1 cgd
43 1.4 mycroft #include <sys/param.h>
44 1.4 mycroft #include <sys/systm.h>
45 1.6 mycroft #include <sys/kernel.h>
46 1.4 mycroft #include <sys/buf.h>
47 1.14 thorpej #include <sys/device.h>
48 1.14 thorpej
49 1.14 thorpej #include <machine/autoconf.h>
50 1.15 scottr #include <machine/psl.h>
51 1.14 thorpej
52 1.14 thorpej #include <hp300/hp300/isr.h>
53 1.14 thorpej
54 1.14 thorpej #include <hp300/dev/dioreg.h>
55 1.14 thorpej #include <hp300/dev/diovar.h>
56 1.14 thorpej #include <hp300/dev/diodevs.h>
57 1.14 thorpej
58 1.14 thorpej #include <hp300/dev/dmavar.h>
59 1.4 mycroft
60 1.4 mycroft #include <hp300/dev/nhpibreg.h>
61 1.4 mycroft #include <hp300/dev/hpibvar.h>
62 1.1 cgd
63 1.6 mycroft /*
64 1.6 mycroft * ODD parity table for listen and talk addresses and secondary commands.
65 1.6 mycroft * The TI9914A doesn't produce the parity bit.
66 1.6 mycroft */
67 1.6 mycroft static u_char listnr_par[] = {
68 1.6 mycroft 0040,0241,0242,0043,0244,0045,0046,0247,
69 1.6 mycroft 0250,0051,0052,0253,0054,0255,0256,0057,
70 1.6 mycroft 0260,0061,0062,0263,0064,0265,0266,0067,
71 1.6 mycroft 0070,0271,0272,0073,0274,0075,0076,0277,
72 1.6 mycroft };
73 1.6 mycroft static u_char talker_par[] = {
74 1.6 mycroft 0100,0301,0302,0103,0304,0105,0106,0307,
75 1.6 mycroft 0310,0111,0112,0313,0114,0315,0316,0117,
76 1.6 mycroft 0320,0121,0122,0323,0124,0325,0326,0127,
77 1.6 mycroft 0130,0331,0332,0133,0334,0135,0136,0337,
78 1.6 mycroft };
79 1.6 mycroft static u_char sec_par[] = {
80 1.6 mycroft 0340,0141,0142,0343,0144,0345,0346,0147,
81 1.6 mycroft 0150,0351,0352,0153,0354,0155,0156,0357,
82 1.6 mycroft 0160,0361,0362,0163,0364,0165,0166,0367,
83 1.6 mycroft 0370,0171,0172,0373,0174,0375,0376,0177
84 1.6 mycroft };
85 1.6 mycroft
86 1.14 thorpej void nhpibifc __P((struct nhpibdevice *));
87 1.14 thorpej void nhpibreadtimo __P((void *));
88 1.14 thorpej int nhpibwait __P((struct nhpibdevice *, int));
89 1.14 thorpej
90 1.14 thorpej void nhpibreset __P((struct hpibbus_softc *));
91 1.14 thorpej int nhpibsend __P((struct hpibbus_softc *, int, int, void *, int));
92 1.14 thorpej int nhpibrecv __P((struct hpibbus_softc *, int, int, void *, int));
93 1.14 thorpej int nhpibppoll __P((struct hpibbus_softc *));
94 1.7 thorpej void nhpibppwatch __P((void *));
95 1.14 thorpej void nhpibgo __P((struct hpibbus_softc *, int, int, void *, int, int, int));
96 1.14 thorpej void nhpibdone __P((struct hpibbus_softc *));
97 1.9 thorpej int nhpibintr __P((void *));
98 1.7 thorpej
99 1.7 thorpej /*
100 1.7 thorpej * Our controller ops structure.
101 1.7 thorpej */
102 1.7 thorpej struct hpib_controller nhpib_controller = {
103 1.7 thorpej nhpibreset,
104 1.7 thorpej nhpibsend,
105 1.7 thorpej nhpibrecv,
106 1.7 thorpej nhpibppoll,
107 1.7 thorpej nhpibppwatch,
108 1.7 thorpej nhpibgo,
109 1.7 thorpej nhpibdone,
110 1.7 thorpej nhpibintr
111 1.7 thorpej };
112 1.7 thorpej
113 1.14 thorpej struct nhpib_softc {
114 1.14 thorpej struct device sc_dev; /* generic device glue */
115 1.14 thorpej struct nhpibdevice *sc_regs; /* device registers */
116 1.14 thorpej struct hpibbus_softc *sc_hpibbus; /* XXX */
117 1.14 thorpej };
118 1.14 thorpej
119 1.14 thorpej int nhpibmatch __P((struct device *, struct cfdata *, void *));
120 1.14 thorpej void nhpibattach __P((struct device *, struct device *, void *));
121 1.14 thorpej
122 1.14 thorpej struct cfattach nhpib_ca = {
123 1.14 thorpej sizeof(struct nhpib_softc), nhpibmatch, nhpibattach
124 1.14 thorpej };
125 1.14 thorpej
126 1.14 thorpej struct cfdriver nhpib_cd = {
127 1.14 thorpej NULL, "nhpib", DV_DULL
128 1.14 thorpej };
129 1.14 thorpej
130 1.7 thorpej int
131 1.14 thorpej nhpibmatch(parent, match, aux)
132 1.14 thorpej struct device *parent;
133 1.14 thorpej struct cfdata *match;
134 1.14 thorpej void *aux;
135 1.1 cgd {
136 1.14 thorpej struct dio_attach_args *da = aux;
137 1.1 cgd
138 1.14 thorpej /*
139 1.14 thorpej * Internal HP-IB doesn't always return a device ID,
140 1.14 thorpej * so we rely on the sysflags.
141 1.14 thorpej */
142 1.14 thorpej if (da->da_scode == 7 && internalhpib)
143 1.8 thorpej return (1);
144 1.14 thorpej
145 1.14 thorpej if (da->da_id == DIO_DEVICE_ID_NHPIB)
146 1.8 thorpej return (1);
147 1.8 thorpej
148 1.14 thorpej return (0);
149 1.8 thorpej }
150 1.8 thorpej
151 1.8 thorpej void
152 1.14 thorpej nhpibattach(parent, self, aux)
153 1.14 thorpej struct device *parent, *self;
154 1.14 thorpej void *aux;
155 1.14 thorpej {
156 1.14 thorpej struct nhpib_softc *sc = (struct nhpib_softc *)self;
157 1.14 thorpej struct dio_attach_args *da = aux;
158 1.14 thorpej struct hpibdev_attach_args ha;
159 1.14 thorpej const char *desc;
160 1.14 thorpej int ipl, type = HPIBA;
161 1.14 thorpej
162 1.14 thorpej sc->sc_regs = (struct nhpibdevice *)iomap(dio_scodetopa(da->da_scode),
163 1.14 thorpej da->da_size);
164 1.14 thorpej if (sc->sc_regs == NULL) {
165 1.14 thorpej printf("\n%s: can't map registers\n", self->dv_xname);
166 1.14 thorpej return;
167 1.14 thorpej }
168 1.8 thorpej
169 1.14 thorpej ipl = DIO_IPL(sc->sc_regs);
170 1.8 thorpej
171 1.14 thorpej if (da->da_scode == 7 && internalhpib)
172 1.14 thorpej desc = DIO_DEVICE_DESC_IHPIB;
173 1.14 thorpej else if (da->da_id == DIO_DEVICE_ID_NHPIB) {
174 1.14 thorpej type = HPIBB;
175 1.14 thorpej desc = DIO_DEVICE_DESC_NHPIB;
176 1.14 thorpej } else
177 1.14 thorpej desc = "unknown HP-IB!";
178 1.14 thorpej
179 1.14 thorpej printf(" ipl %d: %s\n", ipl, desc);
180 1.14 thorpej
181 1.14 thorpej /* Establish the interrupt handler. */
182 1.14 thorpej (void) isrlink(nhpibintr, sc, ipl, ISRPRI_BIO);
183 1.14 thorpej dmacomputeipl();
184 1.14 thorpej
185 1.14 thorpej ha.ha_ops = &nhpib_controller;
186 1.14 thorpej ha.ha_type = type; /* XXX */
187 1.14 thorpej ha.ha_ba = (type == HPIBA) ? HPIBA_BA :
188 1.14 thorpej (sc->sc_regs->hpib_csa & CSA_BA);
189 1.14 thorpej ha.ha_softcpp = &sc->sc_hpibbus; /* XXX */
190 1.14 thorpej (void)config_found(self, &ha, hpibdevprint);
191 1.1 cgd }
192 1.1 cgd
193 1.7 thorpej void
194 1.14 thorpej nhpibreset(hs)
195 1.14 thorpej struct hpibbus_softc *hs;
196 1.1 cgd {
197 1.14 thorpej struct nhpib_softc *sc = (struct nhpib_softc *)hs->sc_dev.dv_parent;
198 1.14 thorpej struct nhpibdevice *hd = sc->sc_regs;
199 1.1 cgd
200 1.1 cgd hd->hpib_acr = AUX_SSWRST;
201 1.1 cgd hd->hpib_ar = hs->sc_ba;
202 1.1 cgd hd->hpib_lim = LIS_ERR;
203 1.1 cgd hd->hpib_mim = 0;
204 1.1 cgd hd->hpib_acr = AUX_CDAI;
205 1.1 cgd hd->hpib_acr = AUX_CSHDW;
206 1.1 cgd hd->hpib_acr = AUX_SSTD1;
207 1.1 cgd hd->hpib_acr = AUX_SVSTD1;
208 1.1 cgd hd->hpib_acr = AUX_CPP;
209 1.1 cgd hd->hpib_acr = AUX_CHDFA;
210 1.1 cgd hd->hpib_acr = AUX_CHDFE;
211 1.1 cgd hd->hpib_acr = AUX_RHDF;
212 1.1 cgd hd->hpib_acr = AUX_CSWRST;
213 1.1 cgd nhpibifc(hd);
214 1.1 cgd hd->hpib_ie = IDS_IE;
215 1.6 mycroft hd->hpib_data = C_DCL_P;
216 1.1 cgd DELAY(100000);
217 1.1 cgd }
218 1.1 cgd
219 1.14 thorpej void
220 1.1 cgd nhpibifc(hd)
221 1.15 scottr struct nhpibdevice *hd;
222 1.1 cgd {
223 1.1 cgd hd->hpib_acr = AUX_TCA;
224 1.1 cgd hd->hpib_acr = AUX_CSRE;
225 1.1 cgd hd->hpib_acr = AUX_SSIC;
226 1.1 cgd DELAY(100);
227 1.1 cgd hd->hpib_acr = AUX_CSIC;
228 1.1 cgd hd->hpib_acr = AUX_SSRE;
229 1.1 cgd }
230 1.1 cgd
231 1.7 thorpej int
232 1.14 thorpej nhpibsend(hs, slave, sec, ptr, origcnt)
233 1.14 thorpej struct hpibbus_softc *hs;
234 1.14 thorpej int slave, sec, origcnt;
235 1.7 thorpej void *ptr;
236 1.1 cgd {
237 1.14 thorpej struct nhpib_softc *sc = (struct nhpib_softc *)hs->sc_dev.dv_parent;
238 1.14 thorpej struct nhpibdevice *hd = sc->sc_regs;
239 1.14 thorpej int cnt = origcnt;
240 1.7 thorpej char *addr = ptr;
241 1.1 cgd
242 1.1 cgd hd->hpib_acr = AUX_TCA;
243 1.6 mycroft hd->hpib_data = C_UNL_P;
244 1.1 cgd if (nhpibwait(hd, MIS_BO))
245 1.1 cgd goto senderror;
246 1.6 mycroft hd->hpib_data = talker_par[hs->sc_ba];
247 1.1 cgd hd->hpib_acr = AUX_STON;
248 1.1 cgd if (nhpibwait(hd, MIS_BO))
249 1.1 cgd goto senderror;
250 1.6 mycroft hd->hpib_data = listnr_par[slave];
251 1.1 cgd if (nhpibwait(hd, MIS_BO))
252 1.1 cgd goto senderror;
253 1.6 mycroft if (sec >= 0 || sec == -2) {
254 1.6 mycroft if (sec == -2) /* selected device clear KLUDGE */
255 1.6 mycroft hd->hpib_data = C_SDC_P;
256 1.6 mycroft else
257 1.6 mycroft hd->hpib_data = sec_par[sec];
258 1.1 cgd if (nhpibwait(hd, MIS_BO))
259 1.1 cgd goto senderror;
260 1.1 cgd }
261 1.1 cgd hd->hpib_acr = AUX_GTS;
262 1.1 cgd if (cnt) {
263 1.1 cgd while (--cnt > 0) {
264 1.1 cgd hd->hpib_data = *addr++;
265 1.1 cgd if (nhpibwait(hd, MIS_BO))
266 1.1 cgd goto senderror;
267 1.1 cgd }
268 1.1 cgd hd->hpib_acr = AUX_EOI;
269 1.1 cgd hd->hpib_data = *addr;
270 1.1 cgd if (nhpibwait(hd, MIS_BO))
271 1.1 cgd goto senderror;
272 1.1 cgd hd->hpib_acr = AUX_TCA;
273 1.1 cgd #if 0
274 1.1 cgd /*
275 1.1 cgd * May be causing 345 disks to hang due to interference
276 1.1 cgd * with PPOLL mechanism.
277 1.1 cgd */
278 1.6 mycroft hd->hpib_data = C_UNL_P;
279 1.1 cgd (void) nhpibwait(hd, MIS_BO);
280 1.1 cgd #endif
281 1.1 cgd }
282 1.1 cgd return(origcnt);
283 1.6 mycroft
284 1.1 cgd senderror:
285 1.1 cgd nhpibifc(hd);
286 1.1 cgd return(origcnt - cnt - 1);
287 1.1 cgd }
288 1.1 cgd
289 1.7 thorpej int
290 1.14 thorpej nhpibrecv(hs, slave, sec, ptr, origcnt)
291 1.14 thorpej struct hpibbus_softc *hs;
292 1.14 thorpej int slave, sec, origcnt;
293 1.7 thorpej void *ptr;
294 1.1 cgd {
295 1.14 thorpej struct nhpib_softc *sc = (struct nhpib_softc *)hs->sc_dev.dv_parent;
296 1.14 thorpej struct nhpibdevice *hd = sc->sc_regs;
297 1.14 thorpej int cnt = origcnt;
298 1.7 thorpej char *addr = ptr;
299 1.1 cgd
300 1.6 mycroft /*
301 1.6 mycroft * Slave < 0 implies continuation of a previous receive
302 1.6 mycroft * that probably timed out.
303 1.6 mycroft */
304 1.6 mycroft if (slave >= 0) {
305 1.6 mycroft hd->hpib_acr = AUX_TCA;
306 1.6 mycroft hd->hpib_data = C_UNL_P;
307 1.6 mycroft if (nhpibwait(hd, MIS_BO))
308 1.6 mycroft goto recverror;
309 1.6 mycroft hd->hpib_data = listnr_par[hs->sc_ba];
310 1.6 mycroft hd->hpib_acr = AUX_SLON;
311 1.6 mycroft if (nhpibwait(hd, MIS_BO))
312 1.6 mycroft goto recverror;
313 1.6 mycroft hd->hpib_data = talker_par[slave];
314 1.1 cgd if (nhpibwait(hd, MIS_BO))
315 1.1 cgd goto recverror;
316 1.6 mycroft if (sec >= 0) {
317 1.6 mycroft hd->hpib_data = sec_par[sec];
318 1.6 mycroft if (nhpibwait(hd, MIS_BO))
319 1.6 mycroft goto recverror;
320 1.6 mycroft }
321 1.6 mycroft hd->hpib_acr = AUX_RHDF;
322 1.6 mycroft hd->hpib_acr = AUX_GTS;
323 1.1 cgd }
324 1.1 cgd if (cnt) {
325 1.1 cgd while (--cnt >= 0) {
326 1.1 cgd if (nhpibwait(hd, MIS_BI))
327 1.1 cgd goto recvbyteserror;
328 1.1 cgd *addr++ = hd->hpib_data;
329 1.1 cgd }
330 1.1 cgd hd->hpib_acr = AUX_TCA;
331 1.6 mycroft hd->hpib_data = (slave == 31) ? C_UNA_P : C_UNT_P;
332 1.1 cgd (void) nhpibwait(hd, MIS_BO);
333 1.1 cgd }
334 1.1 cgd return(origcnt);
335 1.6 mycroft
336 1.1 cgd recverror:
337 1.1 cgd nhpibifc(hd);
338 1.1 cgd recvbyteserror:
339 1.1 cgd return(origcnt - cnt - 1);
340 1.1 cgd }
341 1.1 cgd
342 1.7 thorpej void
343 1.14 thorpej nhpibgo(hs, slave, sec, ptr, count, rw, timo)
344 1.14 thorpej struct hpibbus_softc *hs;
345 1.14 thorpej int slave, sec, count, rw, timo;
346 1.7 thorpej void *ptr;
347 1.1 cgd {
348 1.14 thorpej struct nhpib_softc *sc = (struct nhpib_softc *)hs->sc_dev.dv_parent;
349 1.14 thorpej struct nhpibdevice *hd = sc->sc_regs;
350 1.7 thorpej char *addr = ptr;
351 1.1 cgd
352 1.1 cgd hs->sc_flags |= HPIBF_IO;
353 1.6 mycroft if (timo)
354 1.6 mycroft hs->sc_flags |= HPIBF_TIMO;
355 1.1 cgd if (rw == B_READ)
356 1.1 cgd hs->sc_flags |= HPIBF_READ;
357 1.1 cgd #ifdef DEBUG
358 1.1 cgd else if (hs->sc_flags & HPIBF_READ) {
359 1.13 christos printf("nhpibgo: HPIBF_READ still set\n");
360 1.1 cgd hs->sc_flags &= ~HPIBF_READ;
361 1.1 cgd }
362 1.1 cgd #endif
363 1.1 cgd hs->sc_count = count;
364 1.1 cgd hs->sc_addr = addr;
365 1.1 cgd if (hs->sc_flags & HPIBF_READ) {
366 1.1 cgd hs->sc_curcnt = count;
367 1.14 thorpej dmago(hs->sc_dq->dq_chan, addr, count, DMAGO_BYTE|DMAGO_READ);
368 1.14 thorpej nhpibrecv(hs, slave, sec, 0, 0);
369 1.1 cgd hd->hpib_mim = MIS_END;
370 1.1 cgd } else {
371 1.1 cgd hd->hpib_mim = 0;
372 1.1 cgd if (count < hpibdmathresh) {
373 1.1 cgd hs->sc_curcnt = count;
374 1.14 thorpej nhpibsend(hs, slave, sec, addr, count);
375 1.14 thorpej nhpibdone(hs);
376 1.1 cgd return;
377 1.1 cgd }
378 1.1 cgd hs->sc_curcnt = --count;
379 1.14 thorpej dmago(hs->sc_dq->dq_chan, addr, count, DMAGO_BYTE);
380 1.14 thorpej nhpibsend(hs, slave, sec, 0, 0);
381 1.1 cgd }
382 1.14 thorpej hd->hpib_ie = IDS_IE | IDS_DMA(hs->sc_dq->dq_chan);
383 1.1 cgd }
384 1.1 cgd
385 1.6 mycroft /*
386 1.6 mycroft * This timeout can only happen if a DMA read finishes DMAing with the read
387 1.6 mycroft * still pending (more data in read transaction than the driver was prepared
388 1.6 mycroft * to accept). At the moment, variable-record tape drives are the only things
389 1.6 mycroft * capabale of doing this. We repeat the necessary code from nhpibintr() -
390 1.6 mycroft * easier and quicker than calling nhpibintr() for this special case.
391 1.6 mycroft */
392 1.6 mycroft void
393 1.6 mycroft nhpibreadtimo(arg)
394 1.6 mycroft void *arg;
395 1.6 mycroft {
396 1.14 thorpej struct hpibbus_softc *hs = arg;
397 1.14 thorpej struct nhpib_softc *sc = (struct nhpib_softc *)hs->sc_dev.dv_parent;
398 1.6 mycroft int s = splbio();
399 1.6 mycroft
400 1.6 mycroft if (hs->sc_flags & HPIBF_IO) {
401 1.15 scottr struct nhpibdevice *hd = sc->sc_regs;
402 1.15 scottr struct hpibqueue *hq;
403 1.6 mycroft
404 1.6 mycroft hd->hpib_mim = 0;
405 1.6 mycroft hd->hpib_acr = AUX_TCA;
406 1.6 mycroft hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
407 1.14 thorpej dmafree(hs->sc_dq);
408 1.14 thorpej
409 1.14 thorpej hq = hs->sc_queue.tqh_first;
410 1.14 thorpej (hq->hq_intr)(hq->hq_softc);
411 1.6 mycroft }
412 1.14 thorpej splx(s);
413 1.6 mycroft }
414 1.6 mycroft
415 1.7 thorpej void
416 1.14 thorpej nhpibdone(hs)
417 1.14 thorpej struct hpibbus_softc *hs;
418 1.1 cgd {
419 1.14 thorpej struct nhpib_softc *sc = (struct nhpib_softc *)hs->sc_dev.dv_parent;
420 1.14 thorpej struct nhpibdevice *hd = sc->sc_regs;
421 1.14 thorpej int cnt;
422 1.1 cgd
423 1.1 cgd cnt = hs->sc_curcnt;
424 1.1 cgd hs->sc_addr += cnt;
425 1.1 cgd hs->sc_count -= cnt;
426 1.1 cgd hs->sc_flags |= HPIBF_DONE;
427 1.1 cgd hd->hpib_ie = IDS_IE;
428 1.6 mycroft if (hs->sc_flags & HPIBF_READ) {
429 1.6 mycroft if ((hs->sc_flags & HPIBF_TIMO) &&
430 1.6 mycroft (hd->hpib_ids & IDS_IR) == 0)
431 1.14 thorpej timeout(nhpibreadtimo, hs, hz >> 2);
432 1.6 mycroft } else {
433 1.1 cgd if (hs->sc_count == 1) {
434 1.1 cgd (void) nhpibwait(hd, MIS_BO);
435 1.1 cgd hd->hpib_acr = AUX_EOI;
436 1.1 cgd hd->hpib_data = *hs->sc_addr;
437 1.1 cgd hd->hpib_mim = MIS_BO;
438 1.1 cgd }
439 1.1 cgd #ifdef DEBUG
440 1.1 cgd else if (hs->sc_count)
441 1.1 cgd panic("nhpibdone");
442 1.1 cgd #endif
443 1.1 cgd }
444 1.1 cgd }
445 1.1 cgd
446 1.7 thorpej int
447 1.9 thorpej nhpibintr(arg)
448 1.9 thorpej void *arg;
449 1.1 cgd {
450 1.14 thorpej struct nhpib_softc *sc = arg;
451 1.14 thorpej struct hpibbus_softc *hs = sc->sc_hpibbus;
452 1.14 thorpej struct nhpibdevice *hd = sc->sc_regs;
453 1.14 thorpej struct hpibqueue *hq;
454 1.14 thorpej int stat0;
455 1.14 thorpej int stat1;
456 1.1 cgd
457 1.1 cgd #ifdef lint
458 1.1 cgd if (stat1 = unit) return(1);
459 1.1 cgd #endif
460 1.1 cgd if ((hd->hpib_ids & IDS_IR) == 0)
461 1.1 cgd return(0);
462 1.1 cgd stat0 = hd->hpib_mis;
463 1.1 cgd stat1 = hd->hpib_lis;
464 1.14 thorpej
465 1.14 thorpej hq = hs->sc_queue.tqh_first;
466 1.14 thorpej
467 1.1 cgd if (hs->sc_flags & HPIBF_IO) {
468 1.1 cgd hd->hpib_mim = 0;
469 1.6 mycroft if ((hs->sc_flags & HPIBF_DONE) == 0) {
470 1.6 mycroft hs->sc_flags &= ~HPIBF_TIMO;
471 1.14 thorpej dmastop(hs->sc_dq->dq_chan);
472 1.6 mycroft } else if (hs->sc_flags & HPIBF_TIMO)
473 1.14 thorpej untimeout(nhpibreadtimo, hs);
474 1.1 cgd hd->hpib_acr = AUX_TCA;
475 1.6 mycroft hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
476 1.14 thorpej
477 1.14 thorpej dmafree(hs->sc_dq);
478 1.14 thorpej (hq->hq_intr)(hq->hq_softc);
479 1.1 cgd } else if (hs->sc_flags & HPIBF_PPOLL) {
480 1.1 cgd hd->hpib_mim = 0;
481 1.14 thorpej stat0 = nhpibppoll(hs);
482 1.14 thorpej if (stat0 & (0x80 >> hq->hq_slave)) {
483 1.1 cgd hs->sc_flags &= ~HPIBF_PPOLL;
484 1.14 thorpej (hq->hq_intr)(hq->hq_softc);
485 1.1 cgd }
486 1.1 cgd #ifdef DEBUG
487 1.1 cgd else
488 1.13 christos printf("%s: PPOLL intr bad status %x\n",
489 1.14 thorpej hs->sc_dev.dv_xname, stat0);
490 1.1 cgd #endif
491 1.1 cgd }
492 1.1 cgd return(1);
493 1.1 cgd }
494 1.1 cgd
495 1.7 thorpej int
496 1.14 thorpej nhpibppoll(hs)
497 1.14 thorpej struct hpibbus_softc *hs;
498 1.1 cgd {
499 1.14 thorpej struct nhpib_softc *sc = (struct nhpib_softc *)hs->sc_dev.dv_parent;
500 1.14 thorpej struct nhpibdevice *hd = sc->sc_regs;
501 1.14 thorpej int ppoll;
502 1.1 cgd
503 1.1 cgd hd->hpib_acr = AUX_SPP;
504 1.1 cgd DELAY(25);
505 1.1 cgd ppoll = hd->hpib_cpt;
506 1.1 cgd hd->hpib_acr = AUX_CPP;
507 1.1 cgd return(ppoll);
508 1.1 cgd }
509 1.1 cgd
510 1.6 mycroft #ifdef DEBUG
511 1.6 mycroft int nhpibreporttimo = 0;
512 1.6 mycroft #endif
513 1.6 mycroft
514 1.7 thorpej int
515 1.1 cgd nhpibwait(hd, x)
516 1.15 scottr struct nhpibdevice *hd;
517 1.4 mycroft int x;
518 1.1 cgd {
519 1.15 scottr int timo = hpibtimeout;
520 1.1 cgd
521 1.1 cgd while ((hd->hpib_mis & x) == 0 && --timo)
522 1.11 thorpej DELAY(1);
523 1.6 mycroft if (timo == 0) {
524 1.6 mycroft #ifdef DEBUG
525 1.6 mycroft if (nhpibreporttimo)
526 1.13 christos printf("hpib0: %s timo\n", x==MIS_BO?"OUT":"IN");
527 1.6 mycroft #endif
528 1.1 cgd return(-1);
529 1.6 mycroft }
530 1.1 cgd return(0);
531 1.1 cgd }
532 1.1 cgd
533 1.4 mycroft void
534 1.3 mycroft nhpibppwatch(arg)
535 1.3 mycroft void *arg;
536 1.1 cgd {
537 1.14 thorpej struct hpibbus_softc *hs = arg;
538 1.14 thorpej struct nhpib_softc *sc = (struct nhpib_softc *)hs->sc_dev.dv_parent;
539 1.4 mycroft extern int cold;
540 1.1 cgd
541 1.1 cgd if ((hs->sc_flags & HPIBF_PPOLL) == 0)
542 1.1 cgd return;
543 1.4 mycroft again:
544 1.14 thorpej if (nhpibppoll(hs) & (0x80 >> hs->sc_queue.tqh_first->hq_slave))
545 1.14 thorpej sc->sc_regs->hpib_mim = MIS_BO;
546 1.4 mycroft else if (cold)
547 1.4 mycroft /* timeouts not working yet */
548 1.4 mycroft goto again;
549 1.1 cgd else
550 1.14 thorpej timeout(nhpibppwatch, hs, 1);
551 1.1 cgd }
552