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