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