fhpib.c revision 1.19 1 /* $NetBSD: fhpib.c,v 1.19 1997/10/04 09:59:49 thorpej 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 * @(#)fhpib.c 8.2 (Berkeley) 1/12/94
72 */
73
74 /*
75 * 98625A/B HPIB driver
76 */
77
78 #include <sys/param.h>
79 #include <sys/systm.h>
80 #include <sys/kernel.h>
81 #include <sys/buf.h>
82 #include <sys/device.h>
83
84 #include <machine/autoconf.h>
85 #include <machine/intr.h>
86
87 #include <hp300/dev/dioreg.h>
88 #include <hp300/dev/diovar.h>
89 #include <hp300/dev/diodevs.h>
90
91 #include <hp300/dev/dmavar.h>
92
93 #include <hp300/dev/fhpibreg.h>
94 #include <hp300/dev/hpibvar.h>
95
96 /*
97 * Inline version of fhpibwait to be used in places where
98 * we don't worry about getting hung.
99 */
100 #define FHPIBWAIT(hd, m) while (((hd)->hpib_intr & (m)) == 0) DELAY(1)
101
102 #ifdef DEBUG
103 int fhpibdebugunit = -1;
104 int fhpibdebug = 0;
105 #define FDB_FAIL 0x01
106 #define FDB_DMA 0x02
107 #define FDB_WAIT 0x04
108 #define FDB_PPOLL 0x08
109
110 int dopriodma = 0; /* use high priority DMA */
111 int doworddma = 1; /* non-zero if we should attempt word dma */
112 int doppollint = 1; /* use ppoll interrupts instead of watchdog */
113 int fhpibppolldelay = 50;
114 #endif
115
116 void fhpibifc __P((struct fhpibdevice *));
117 void fhpibdmadone __P((void *));
118 int fhpibwait __P((struct fhpibdevice *, int));
119
120 void fhpibreset __P((struct hpibbus_softc *));
121 int fhpibsend __P((struct hpibbus_softc *, int, int, void *, int));
122 int fhpibrecv __P((struct hpibbus_softc *, int, int, void *, int));
123 int fhpibppoll __P((struct hpibbus_softc *));
124 void fhpibppwatch __P((void *));
125 void fhpibgo __P((struct hpibbus_softc *, int, int, void *, int, int, int));
126 void fhpibdone __P((struct hpibbus_softc *));
127 int fhpibintr __P((void *));
128
129 /*
130 * Our controller ops structure.
131 */
132 struct hpib_controller fhpib_controller = {
133 fhpibreset,
134 fhpibsend,
135 fhpibrecv,
136 fhpibppoll,
137 fhpibppwatch,
138 fhpibgo,
139 fhpibdone,
140 fhpibintr
141 };
142
143 struct fhpib_softc {
144 struct device sc_dev; /* generic device glue */
145 struct fhpibdevice *sc_regs; /* device registers */
146 int sc_cmd;
147 struct hpibbus_softc *sc_hpibbus; /* XXX */
148 };
149
150 int fhpibmatch __P((struct device *, struct cfdata *, void *));
151 void fhpibattach __P((struct device *, struct device *, void *));
152
153 struct cfattach fhpib_ca = {
154 sizeof(struct fhpib_softc), fhpibmatch, fhpibattach
155 };
156
157 struct cfdriver fhpib_cd = {
158 NULL, "fhpib", DV_DULL
159 };
160
161 int
162 fhpibmatch(parent, match, aux)
163 struct device *parent;
164 struct cfdata *match;
165 void *aux;
166 {
167 struct dio_attach_args *da = aux;
168
169 if (da->da_id == DIO_DEVICE_ID_FHPIB)
170 return (1);
171
172 return (0);
173 }
174
175 void
176 fhpibattach(parent, self, aux)
177 struct device *parent, *self;
178 void *aux;
179 {
180 struct fhpib_softc *sc = (struct fhpib_softc *)self;
181 struct dio_attach_args *da = aux;
182 struct hpibdev_attach_args ha;
183 int ipl;
184
185 sc->sc_regs = (struct fhpibdevice *)iomap(dio_scodetopa(da->da_scode),
186 da->da_size);
187 if (sc->sc_regs == NULL) {
188 printf("\n%s: can't map registers\n", self->dv_xname);
189 return;
190 }
191
192 ipl = DIO_IPL(sc->sc_regs);
193 printf(" ipl %d: %s\n", ipl, DIO_DEVICE_DESC_FHPIB);
194
195 /* Establish the interrupt handler. */
196 (void) dio_intr_establish(fhpibintr, sc, ipl, IPL_BIO);
197
198 ha.ha_ops = &fhpib_controller;
199 ha.ha_type = HPIBC; /* XXX */
200 ha.ha_ba = HPIBC_BA;
201 ha.ha_softcpp = &sc->sc_hpibbus; /* XXX */
202 (void)config_found(self, &ha, hpibdevprint);
203 }
204
205 void
206 fhpibreset(hs)
207 struct hpibbus_softc *hs;
208 {
209 struct fhpib_softc *sc = (struct fhpib_softc *)hs->sc_dev.dv_parent;
210 struct fhpibdevice *hd = sc->sc_regs;
211
212 hd->hpib_cid = 0xFF;
213 DELAY(100);
214 hd->hpib_cmd = CT_8BIT;
215 hd->hpib_ar = AR_ARONC;
216 fhpibifc(hd);
217 hd->hpib_ie = IDS_IE;
218 hd->hpib_data = C_DCL;
219 DELAY(100000);
220 /*
221 * See if we can do word dma.
222 * If so, we should be able to write and read back the appropos bit.
223 */
224 hd->hpib_ie |= IDS_WDMA;
225 if (hd->hpib_ie & IDS_WDMA) {
226 hd->hpib_ie &= ~IDS_WDMA;
227 hs->sc_flags |= HPIBF_DMA16;
228 #ifdef DEBUG
229 if (fhpibdebug & FDB_DMA)
230 printf("fhpibtype: %s has word dma\n",
231 sc->sc_dev.dv_xname);
232
233 #endif
234 }
235 }
236
237 void
238 fhpibifc(hd)
239 struct fhpibdevice *hd;
240 {
241 hd->hpib_cmd |= CT_IFC;
242 hd->hpib_cmd |= CT_INITFIFO;
243 DELAY(100);
244 hd->hpib_cmd &= ~CT_IFC;
245 hd->hpib_cmd |= CT_REN;
246 hd->hpib_stat = ST_ATN;
247 }
248
249 int
250 fhpibsend(hs, slave, sec, ptr, origcnt)
251 struct hpibbus_softc *hs;
252 int slave, sec, origcnt;
253 void *ptr;
254 {
255 struct fhpib_softc *sc = (struct fhpib_softc *)hs->sc_dev.dv_parent;
256 struct fhpibdevice *hd = sc->sc_regs;
257 int cnt = origcnt;
258 int timo;
259 char *addr = ptr;
260
261 hd->hpib_stat = 0;
262 hd->hpib_imask = IM_IDLE | IM_ROOM;
263 if (fhpibwait(hd, IM_IDLE) < 0)
264 goto senderr;
265 hd->hpib_stat = ST_ATN;
266 hd->hpib_data = C_UNL;
267 hd->hpib_data = C_TAG + hs->sc_ba;
268 hd->hpib_data = C_LAG + slave;
269 if (sec < 0) {
270 if (sec == -2) /* selected device clear KLUDGE */
271 hd->hpib_data = C_SDC;
272 } else
273 hd->hpib_data = C_SCG + sec;
274 if (fhpibwait(hd, IM_IDLE) < 0)
275 goto senderr;
276 if (cnt) {
277 hd->hpib_stat = ST_WRITE;
278 while (--cnt) {
279 hd->hpib_data = *addr++;
280 timo = hpibtimeout;
281 while ((hd->hpib_intr & IM_ROOM) == 0) {
282 if (--timo <= 0)
283 goto senderr;
284 DELAY(1);
285 }
286 }
287 hd->hpib_stat = ST_EOI;
288 hd->hpib_data = *addr;
289 FHPIBWAIT(hd, IM_ROOM);
290 hd->hpib_stat = ST_ATN;
291 /* XXX: HP-UX claims bug with CS80 transparent messages */
292 if (sec == 0x12)
293 DELAY(150);
294 hd->hpib_data = C_UNL;
295 (void) fhpibwait(hd, IM_IDLE);
296 }
297 hd->hpib_imask = 0;
298 return (origcnt);
299
300 senderr:
301 hd->hpib_imask = 0;
302 fhpibifc(hd);
303 #ifdef DEBUG
304 if (fhpibdebug & FDB_FAIL) {
305 printf("%s: fhpibsend failed: slave %d, sec %x, ",
306 sc->sc_dev.dv_xname, slave, sec);
307 printf("sent %d of %d bytes\n", origcnt-cnt-1, origcnt);
308 }
309 #endif
310 return (origcnt - cnt - 1);
311 }
312
313 int
314 fhpibrecv(hs, slave, sec, ptr, origcnt)
315 struct hpibbus_softc *hs;
316 int slave, sec, origcnt;
317 void *ptr;
318 {
319 struct fhpib_softc *sc = (struct fhpib_softc *)hs->sc_dev.dv_parent;
320 struct fhpibdevice *hd = sc->sc_regs;
321 int cnt = origcnt;
322 int timo;
323 char *addr = ptr;
324
325 /*
326 * Slave < 0 implies continuation of a previous receive
327 * that probably timed out.
328 */
329 if (slave >= 0) {
330 hd->hpib_stat = 0;
331 hd->hpib_imask = IM_IDLE | IM_ROOM | IM_BYTE;
332 if (fhpibwait(hd, IM_IDLE) < 0)
333 goto recverror;
334 hd->hpib_stat = ST_ATN;
335 hd->hpib_data = C_UNL;
336 hd->hpib_data = C_LAG + hs->sc_ba;
337 hd->hpib_data = C_TAG + slave;
338 if (sec != -1)
339 hd->hpib_data = C_SCG + sec;
340 if (fhpibwait(hd, IM_IDLE) < 0)
341 goto recverror;
342 hd->hpib_stat = ST_READ0;
343 hd->hpib_data = 0;
344 }
345 if (cnt) {
346 while (--cnt >= 0) {
347 timo = hpibtimeout;
348 while ((hd->hpib_intr & IM_BYTE) == 0) {
349 if (--timo == 0)
350 goto recvbyteserror;
351 DELAY(1);
352 }
353 *addr++ = hd->hpib_data;
354 }
355 FHPIBWAIT(hd, IM_ROOM);
356 hd->hpib_stat = ST_ATN;
357 hd->hpib_data = (slave == 31) ? C_UNA : C_UNT;
358 (void) fhpibwait(hd, IM_IDLE);
359 }
360 hd->hpib_imask = 0;
361 return (origcnt);
362
363 recverror:
364 fhpibifc(hd);
365 recvbyteserror:
366 hd->hpib_imask = 0;
367 #ifdef DEBUG
368 if (fhpibdebug & FDB_FAIL) {
369 printf("%s: fhpibrecv failed: slave %d, sec %x, ",
370 sc->sc_dev.dv_xname, slave, sec);
371 printf("got %d of %d bytes\n", origcnt-cnt-1, origcnt);
372 }
373 #endif
374 return (origcnt - cnt - 1);
375 }
376
377 void
378 fhpibgo(hs, slave, sec, ptr, count, rw, timo)
379 struct hpibbus_softc *hs;
380 int slave, sec, count, rw, timo;
381 void *ptr;
382 {
383 struct fhpib_softc *sc = (struct fhpib_softc *)hs->sc_dev.dv_parent;
384 struct fhpibdevice *hd = sc->sc_regs;
385 int i;
386 char *addr = ptr;
387 int flags = 0;
388
389 hs->sc_flags |= HPIBF_IO;
390 if (timo)
391 hs->sc_flags |= HPIBF_TIMO;
392 if (rw == B_READ)
393 hs->sc_flags |= HPIBF_READ;
394 #ifdef DEBUG
395 else if (hs->sc_flags & HPIBF_READ) {
396 printf("fhpibgo: HPIBF_READ still set\n");
397 hs->sc_flags &= ~HPIBF_READ;
398 }
399 #endif
400 hs->sc_count = count;
401 hs->sc_addr = addr;
402 #ifdef DEBUG
403 /* fhpibtransfer[unit]++; XXX */
404 #endif
405 if ((hs->sc_flags & HPIBF_DMA16) &&
406 ((int)addr & 1) == 0 && count && (count & 1) == 0
407 #ifdef DEBUG
408 && doworddma
409 #endif
410 ) {
411 #ifdef DEBUG
412 /* fhpibworddma[unit]++; XXX */
413 #endif
414 flags |= DMAGO_WORD;
415 hd->hpib_latch = 0;
416 }
417 #ifdef DEBUG
418 if (dopriodma)
419 flags |= DMAGO_PRI;
420 #endif
421 if (hs->sc_flags & HPIBF_READ) {
422 sc->sc_cmd = CT_REN | CT_8BIT;
423 hs->sc_curcnt = count;
424 dmago(hs->sc_dq->dq_chan, addr, count, flags|DMAGO_READ);
425 if (fhpibrecv(hs, slave, sec, 0, 0) < 0) {
426 #ifdef DEBUG
427 printf("fhpibgo: recv failed, retrying...\n");
428 #endif
429 (void) fhpibrecv(hs, slave, sec, 0, 0);
430 }
431 i = hd->hpib_cmd;
432 hd->hpib_cmd = sc->sc_cmd;
433 hd->hpib_ie = IDS_DMA(hs->sc_dq->dq_chan) |
434 ((flags & DMAGO_WORD) ? IDS_WDMA : 0);
435 return;
436 }
437 sc->sc_cmd = CT_REN | CT_8BIT | CT_FIFOSEL;
438 if (count < hpibdmathresh) {
439 #ifdef DEBUG
440 /* fhpibnondma[unit]++; XXX */
441 if (flags & DMAGO_WORD)
442 /* fhpibworddma[unit]--; XXX */ ;
443 #endif
444 hs->sc_curcnt = count;
445 (void) fhpibsend(hs, slave, sec, addr, count);
446 fhpibdone(hs);
447 return;
448 }
449 count -= (flags & DMAGO_WORD) ? 2 : 1;
450 hs->sc_curcnt = count;
451 dmago(hs->sc_dq->dq_chan, addr, count, flags);
452 if (fhpibsend(hs, slave, sec, 0, 0) < 0) {
453 #ifdef DEBUG
454 printf("fhpibgo: send failed, retrying...\n");
455 #endif
456 (void) fhpibsend(hs, slave, sec, 0, 0);
457 }
458 i = hd->hpib_cmd;
459 hd->hpib_cmd = sc->sc_cmd;
460 hd->hpib_ie = IDS_DMA(hs->sc_dq->dq_chan) | IDS_WRITE |
461 ((flags & DMAGO_WORD) ? IDS_WDMA : 0);
462 }
463
464 /*
465 * A DMA read can finish but the device can still be waiting (MAG-tape
466 * with more data than we're waiting for). This timeout routine
467 * takes care of that. Somehow, the thing gets hosed. For now, since
468 * this should be a very rare occurence, we RESET it.
469 */
470 void
471 fhpibdmadone(arg)
472 void *arg;
473 {
474 struct hpibbus_softc *hs = arg;
475 struct fhpib_softc *sc = (struct fhpib_softc *)hs->sc_dev.dv_parent;
476 int s = splbio();
477
478 if (hs->sc_flags & HPIBF_IO) {
479 struct fhpibdevice *hd = sc->sc_regs;
480 struct hpibqueue *hq;
481
482 hd->hpib_imask = 0;
483 hd->hpib_cid = 0xFF;
484 DELAY(100);
485 hd->hpib_cmd = CT_8BIT;
486 hd->hpib_ar = AR_ARONC;
487 fhpibifc(hd);
488 hd->hpib_ie = IDS_IE;
489 hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
490 dmafree(hs->sc_dq);
491
492 hq = hs->sc_queue.tqh_first;
493 (hq->hq_intr)(hq->hq_softc);
494 }
495 splx(s);
496 }
497
498 void
499 fhpibdone(hs)
500 struct hpibbus_softc *hs;
501 {
502 struct fhpib_softc *sc = (struct fhpib_softc *)hs->sc_dev.dv_parent;
503 struct fhpibdevice *hd = sc->sc_regs;
504 char *addr;
505 int cnt;
506
507 cnt = hs->sc_curcnt;
508 hs->sc_addr += cnt;
509 hs->sc_count -= cnt;
510 #ifdef DEBUG
511 if ((fhpibdebug & FDB_DMA) && fhpibdebugunit == sc->sc_dev.dv_unit)
512 printf("fhpibdone: addr %p cnt %d\n",
513 hs->sc_addr, hs->sc_count);
514 #endif
515 if (hs->sc_flags & HPIBF_READ) {
516 hd->hpib_imask = IM_IDLE | IM_BYTE;
517 if (hs->sc_flags & HPIBF_TIMO)
518 timeout(fhpibdmadone, hs, hz >> 2);
519 } else {
520 cnt = hs->sc_count;
521 if (cnt) {
522 addr = hs->sc_addr;
523 hd->hpib_imask = IM_IDLE | IM_ROOM;
524 FHPIBWAIT(hd, IM_IDLE);
525 hd->hpib_stat = ST_WRITE;
526 while (--cnt) {
527 hd->hpib_data = *addr++;
528 FHPIBWAIT(hd, IM_ROOM);
529 }
530 hd->hpib_stat = ST_EOI;
531 hd->hpib_data = *addr;
532 }
533 hd->hpib_imask = IM_IDLE;
534 }
535 hs->sc_flags |= HPIBF_DONE;
536 hd->hpib_stat = ST_IENAB;
537 hd->hpib_ie = IDS_IE;
538 }
539
540 int
541 fhpibintr(arg)
542 void *arg;
543 {
544 struct fhpib_softc *sc = arg;
545 struct hpibbus_softc *hs = sc->sc_hpibbus;
546 struct fhpibdevice *hd = sc->sc_regs;
547 struct hpibqueue *hq;
548 int stat0;
549
550 stat0 = hd->hpib_ids;
551 if ((stat0 & (IDS_IE|IDS_IR)) != (IDS_IE|IDS_IR)) {
552 #ifdef DEBUG
553 if ((fhpibdebug & FDB_FAIL) && (stat0 & IDS_IR) &&
554 (hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) != HPIBF_IO)
555 printf("%s: fhpibintr: bad status %x\n",
556 sc->sc_dev.dv_xname, stat0);
557 /* fhpibbadint[0]++; XXX */
558 #endif
559 return(0);
560 }
561 if ((hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) == HPIBF_IO) {
562 #ifdef DEBUG
563 /* fhpibbadint[1]++; XXX */
564 #endif
565 return(0);
566 }
567 #ifdef DEBUG
568 if ((fhpibdebug & FDB_DMA) && fhpibdebugunit == sc->sc_dev.dv_unit)
569 printf("fhpibintr: flags %x\n", hs->sc_flags);
570 #endif
571 hq = hs->sc_queue.tqh_first;
572 if (hs->sc_flags & HPIBF_IO) {
573 if (hs->sc_flags & HPIBF_TIMO)
574 untimeout(fhpibdmadone, hs);
575 stat0 = hd->hpib_cmd;
576 hd->hpib_cmd = sc->sc_cmd & ~CT_8BIT;
577 hd->hpib_stat = 0;
578 hd->hpib_cmd = CT_REN | CT_8BIT;
579 stat0 = hd->hpib_intr;
580 hd->hpib_imask = 0;
581 hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
582 dmafree(hs->sc_dq);
583 (hq->hq_intr)(hq->hq_softc);
584 } else if (hs->sc_flags & HPIBF_PPOLL) {
585 stat0 = hd->hpib_intr;
586 #ifdef DEBUG
587 if ((fhpibdebug & FDB_FAIL) &&
588 doppollint && (stat0 & IM_PPRESP) == 0)
589 printf("%s: fhpibintr: bad intr reg %x\n",
590 sc->sc_dev.dv_xname, stat0);
591 #endif
592 hd->hpib_stat = 0;
593 hd->hpib_imask = 0;
594 #ifdef DEBUG
595 stat0 = fhpibppoll(hs);
596 if ((fhpibdebug & FDB_PPOLL) &&
597 fhpibdebugunit == sc->sc_dev.dv_unit)
598 printf("fhpibintr: got PPOLL status %x\n", stat0);
599 if ((stat0 & (0x80 >> hq->hq_slave)) == 0) {
600 /*
601 * XXX give it another shot (68040)
602 */
603 /* fhpibppollfail[unit]++; XXX */
604 DELAY(fhpibppolldelay);
605 stat0 = fhpibppoll(hs);
606 if ((stat0 & (0x80 >> hq->hq_slave)) == 0 &&
607 (fhpibdebug & FDB_PPOLL) &&
608 fhpibdebugunit == sc->sc_dev.dv_unit)
609 printf("fhpibintr: PPOLL: unit %d slave %d stat %x\n",
610 sc->sc_dev.dv_unit, hq->hq_slave, stat0);
611 }
612 #endif
613 hs->sc_flags &= ~HPIBF_PPOLL;
614 (hq->hq_intr)(hq->hq_softc);
615 }
616 return(1);
617 }
618
619 int
620 fhpibppoll(hs)
621 struct hpibbus_softc *hs;
622 {
623 struct fhpib_softc *sc = (struct fhpib_softc *)hs->sc_dev.dv_parent;
624 struct fhpibdevice *hd = sc->sc_regs;
625 int ppoll;
626
627 hd->hpib_stat = 0;
628 hd->hpib_psense = 0;
629 hd->hpib_pmask = 0xFF;
630 hd->hpib_imask = IM_PPRESP | IM_PABORT;
631 DELAY(25);
632 hd->hpib_intr = IM_PABORT;
633 ppoll = hd->hpib_data;
634 if (hd->hpib_intr & IM_PABORT)
635 ppoll = 0;
636 hd->hpib_imask = 0;
637 hd->hpib_pmask = 0;
638 hd->hpib_stat = ST_IENAB;
639 return(ppoll);
640 }
641
642 int
643 fhpibwait(hd, x)
644 struct fhpibdevice *hd;
645 int x;
646 {
647 int timo = hpibtimeout;
648
649 while ((hd->hpib_intr & x) == 0 && --timo)
650 DELAY(1);
651 if (timo == 0) {
652 #ifdef DEBUG
653 if (fhpibdebug & FDB_FAIL)
654 printf("fhpibwait(%p, %x) timeout\n", hd, x);
655 #endif
656 return(-1);
657 }
658 return(0);
659 }
660
661 /*
662 * XXX: this will have to change if we ever allow more than one
663 * pending operation per HP-IB.
664 */
665 void
666 fhpibppwatch(arg)
667 void *arg;
668 {
669 struct hpibbus_softc *hs = arg;
670 struct fhpib_softc *sc = (struct fhpib_softc *)hs->sc_dev.dv_parent;
671 struct fhpibdevice *hd = sc->sc_regs;
672 int slave;
673
674 if ((hs->sc_flags & HPIBF_PPOLL) == 0)
675 return;
676 slave = (0x80 >> hs->sc_queue.tqh_first->hq_slave);
677 #ifdef DEBUG
678 if (!doppollint) {
679 if (fhpibppoll(hs) & slave) {
680 hd->hpib_stat = ST_IENAB;
681 hd->hpib_imask = IM_IDLE | IM_ROOM;
682 } else
683 timeout(fhpibppwatch, sc, 1);
684 return;
685 }
686 if ((fhpibdebug & FDB_PPOLL) && sc->sc_dev.dv_unit == fhpibdebugunit)
687 printf("fhpibppwatch: sense request on %s\n",
688 sc->sc_dev.dv_xname);
689 #endif
690 hd->hpib_psense = ~slave;
691 hd->hpib_pmask = slave;
692 hd->hpib_stat = ST_IENAB;
693 hd->hpib_imask = IM_PPRESP | IM_PABORT;
694 hd->hpib_ie = IDS_IE;
695 }
696