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