Sync usage with man page.
[netbsd-mini2440.git] / sys / arch / hp300 / dev / fhpib.c
blob95e0eb36b42045ad9040d8bfa653a3fdbe5a54e1
1 /* $NetBSD: fhpib.c,v 1.38 2008/03/29 06:47:07 tsutsui Exp $ */
3 /*-
4 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe.
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (c) 1982, 1990, 1993
34 * The Regents of the University of California. All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
60 * @(#)fhpib.c 8.2 (Berkeley) 1/12/94
64 * 98625A/B HPIB driver
67 #include <sys/cdefs.h>
68 __KERNEL_RCSID(0, "$NetBSD: fhpib.c,v 1.38 2008/03/29 06:47:07 tsutsui Exp $");
70 #include <sys/param.h>
71 #include <sys/systm.h>
72 #include <sys/callout.h>
73 #include <sys/kernel.h>
74 #include <sys/buf.h>
75 #include <sys/device.h>
77 #include <machine/autoconf.h>
78 #include <machine/intr.h>
80 #include <hp300/dev/diovar.h>
81 #include <hp300/dev/diodevs.h>
83 #include <hp300/dev/dmavar.h>
85 #include <hp300/dev/fhpibreg.h>
86 #include <hp300/dev/hpibvar.h>
89 * Inline version of fhpibwait to be used in places where
90 * we don't worry about getting hung.
92 #define FHPIBWAIT(hd, m) while (((hd)->hpib_intr & (m)) == 0) DELAY(1)
94 #ifdef DEBUG
95 int fhpibdebugunit = -1;
96 int fhpibdebug = 0;
97 #define FDB_FAIL 0x01
98 #define FDB_DMA 0x02
99 #define FDB_WAIT 0x04
100 #define FDB_PPOLL 0x08
102 int dopriodma = 0; /* use high priority DMA */
103 int doworddma = 1; /* non-zero if we should attempt word DMA */
104 int doppollint = 1; /* use ppoll interrupts instead of watchdog */
105 int fhpibppolldelay = 50;
106 #endif
108 static void fhpibifc(struct fhpibdevice *);
109 static void fhpibdmadone(void *);
110 static int fhpibwait(struct fhpibdevice *, int);
112 static void fhpibreset(struct hpibbus_softc *);
113 static int fhpibsend(struct hpibbus_softc *, int, int, void *, int);
114 static int fhpibrecv(struct hpibbus_softc *, int, int, void *, int);
115 static int fhpibppoll(struct hpibbus_softc *);
116 static void fhpibppwatch(void *);
117 static void fhpibgo(struct hpibbus_softc *, int, int, void *, int, int,
118 int);
119 static void fhpibdone(struct hpibbus_softc *);
120 static int fhpibintr(void *);
123 * Our controller ops structure.
125 static struct hpib_controller fhpib_controller = {
126 fhpibreset,
127 fhpibsend,
128 fhpibrecv,
129 fhpibppoll,
130 fhpibppwatch,
131 fhpibgo,
132 fhpibdone,
133 fhpibintr
136 struct fhpib_softc {
137 device_t sc_dev; /* generic device glue */
138 struct fhpibdevice *sc_regs; /* device registers */
139 int sc_cmd;
140 struct hpibbus_softc *sc_hpibbus; /* XXX */
141 struct callout sc_dmadone_ch;
142 struct callout sc_ppwatch_ch;
145 static int fhpibmatch(device_t, cfdata_t, void *);
146 static void fhpibattach(device_t, device_t, void *);
148 CFATTACH_DECL_NEW(fhpib, sizeof(struct fhpib_softc),
149 fhpibmatch, fhpibattach, NULL, NULL);
151 static int
152 fhpibmatch(device_t parent, cfdata_t cf, void *aux)
154 struct dio_attach_args *da = aux;
156 if (da->da_id == DIO_DEVICE_ID_FHPIB)
157 return 1;
159 return 0;
162 static void
163 fhpibattach(device_t parent, device_t self, void *aux)
165 struct fhpib_softc *sc = device_private(self);
166 struct dio_attach_args *da = aux;
167 struct hpibdev_attach_args ha;
168 bus_space_handle_t bsh;
170 sc->sc_dev = self;
171 if (bus_space_map(da->da_bst, da->da_addr, da->da_size, 0, &bsh)) {
172 aprint_error(": can't map registers\n");
173 return;
175 sc->sc_regs = bus_space_vaddr(da->da_bst, bsh);
177 aprint_normal(": %s\n", DIO_DEVICE_DESC_FHPIB);
179 /* Establish the interrupt handler. */
180 (void)dio_intr_establish(fhpibintr, sc, da->da_ipl, IPL_BIO);
182 callout_init(&sc->sc_dmadone_ch, 0);
183 callout_init(&sc->sc_ppwatch_ch, 0);
185 ha.ha_ops = &fhpib_controller;
186 ha.ha_type = HPIBC; /* XXX */
187 ha.ha_ba = HPIBC_BA;
188 ha.ha_softcpp = &sc->sc_hpibbus; /* XXX */
189 (void)config_found(self, &ha, hpibdevprint);
192 static void
193 fhpibreset(struct hpibbus_softc *hs)
195 struct fhpib_softc *sc = device_private(device_parent(hs->sc_dev));
196 struct fhpibdevice *hd = sc->sc_regs;
198 hd->hpib_cid = 0xFF;
199 DELAY(100);
200 hd->hpib_cmd = CT_8BIT;
201 hd->hpib_ar = AR_ARONC;
202 fhpibifc(hd);
203 hd->hpib_ie = IDS_IE;
204 hd->hpib_data = C_DCL;
205 DELAY(100000);
207 * See if we can do word DMA.
208 * If so, we should be able to write and read back the appropos bit.
210 hd->hpib_ie |= IDS_WDMA;
211 if (hd->hpib_ie & IDS_WDMA) {
212 hd->hpib_ie &= ~IDS_WDMA;
213 hs->sc_flags |= HPIBF_DMA16;
214 #ifdef DEBUG
215 if (fhpibdebug & FDB_DMA)
216 printf("fhpibtype: %s has word DMA\n",
217 device_xname(sc->sc_dev));
218 #endif
222 static void
223 fhpibifc(struct fhpibdevice *hd)
226 hd->hpib_cmd |= CT_IFC;
227 hd->hpib_cmd |= CT_INITFIFO;
228 DELAY(100);
229 hd->hpib_cmd &= ~CT_IFC;
230 hd->hpib_cmd |= CT_REN;
231 hd->hpib_stat = ST_ATN;
234 static int
235 fhpibsend(struct hpibbus_softc *hs, int slave, int sec, void *ptr, int origcnt)
237 struct fhpib_softc *sc = device_private(device_parent(hs->sc_dev));
238 struct fhpibdevice *hd = sc->sc_regs;
239 int cnt = origcnt;
240 int timo;
241 char *addr = ptr;
243 hd->hpib_stat = 0;
244 hd->hpib_imask = IM_IDLE | IM_ROOM;
245 if (fhpibwait(hd, IM_IDLE) < 0)
246 goto senderr;
247 hd->hpib_stat = ST_ATN;
248 hd->hpib_data = C_UNL;
249 hd->hpib_data = C_TAG + hs->sc_ba;
250 hd->hpib_data = C_LAG + slave;
251 if (sec < 0) {
252 if (sec == -2) /* selected device clear KLUDGE */
253 hd->hpib_data = C_SDC;
254 } else
255 hd->hpib_data = C_SCG + sec;
256 if (fhpibwait(hd, IM_IDLE) < 0)
257 goto senderr;
258 if (cnt) {
259 hd->hpib_stat = ST_WRITE;
260 while (--cnt) {
261 hd->hpib_data = *addr++;
262 timo = hpibtimeout;
263 while ((hd->hpib_intr & IM_ROOM) == 0) {
264 if (--timo <= 0)
265 goto senderr;
266 DELAY(1);
269 hd->hpib_stat = ST_EOI;
270 hd->hpib_data = *addr;
271 FHPIBWAIT(hd, IM_ROOM);
272 hd->hpib_stat = ST_ATN;
273 /* XXX: HP-UX claims bug with CS80 transparent messages */
274 if (sec == 0x12)
275 DELAY(150);
276 hd->hpib_data = C_UNL;
277 (void) fhpibwait(hd, IM_IDLE);
279 hd->hpib_imask = 0;
280 return origcnt;
282 senderr:
283 hd->hpib_imask = 0;
284 fhpibifc(hd);
285 #ifdef DEBUG
286 if (fhpibdebug & FDB_FAIL) {
287 printf("%s: fhpibsend failed: slave %d, sec %x, ",
288 device_xname(sc->sc_dev), slave, sec);
289 printf("sent %d of %d bytes\n", origcnt-cnt-1, origcnt);
291 #endif
292 return origcnt - cnt - 1;
295 static int
296 fhpibrecv(struct hpibbus_softc *hs, int slave, int sec, void *ptr, int origcnt)
298 struct fhpib_softc *sc = device_private(device_parent(hs->sc_dev));
299 struct fhpibdevice *hd = sc->sc_regs;
300 int cnt = origcnt;
301 int timo;
302 char *addr = ptr;
305 * Slave < 0 implies continuation of a previous receive
306 * that probably timed out.
308 if (slave >= 0) {
309 hd->hpib_stat = 0;
310 hd->hpib_imask = IM_IDLE | IM_ROOM | IM_BYTE;
311 if (fhpibwait(hd, IM_IDLE) < 0)
312 goto recverror;
313 hd->hpib_stat = ST_ATN;
314 hd->hpib_data = C_UNL;
315 hd->hpib_data = C_LAG + hs->sc_ba;
316 hd->hpib_data = C_TAG + slave;
317 if (sec != -1)
318 hd->hpib_data = C_SCG + sec;
319 if (fhpibwait(hd, IM_IDLE) < 0)
320 goto recverror;
321 hd->hpib_stat = ST_READ0;
322 hd->hpib_data = 0;
324 if (cnt) {
325 while (--cnt >= 0) {
326 timo = hpibtimeout;
327 while ((hd->hpib_intr & IM_BYTE) == 0) {
328 if (--timo == 0)
329 goto recvbyteserror;
330 DELAY(1);
332 *addr++ = hd->hpib_data;
334 FHPIBWAIT(hd, IM_ROOM);
335 hd->hpib_stat = ST_ATN;
336 hd->hpib_data = (slave == 31) ? C_UNA : C_UNT;
337 (void) fhpibwait(hd, IM_IDLE);
339 hd->hpib_imask = 0;
340 return origcnt;
342 recverror:
343 fhpibifc(hd);
344 recvbyteserror:
345 hd->hpib_imask = 0;
346 #ifdef DEBUG
347 if (fhpibdebug & FDB_FAIL) {
348 printf("%s: fhpibrecv failed: slave %d, sec %x, ",
349 device_xname(sc->sc_dev), slave, sec);
350 printf("got %d of %d bytes\n", origcnt-cnt-1, origcnt);
352 #endif
353 return origcnt - cnt - 1;
356 static void
357 fhpibgo(struct hpibbus_softc *hs, int slave, int sec, void *ptr, int count,
358 int rw, int timo)
360 struct fhpib_softc *sc = device_private(device_parent(hs->sc_dev));
361 struct fhpibdevice *hd = sc->sc_regs;
362 int i;
363 char *addr = ptr;
364 int flags = 0;
366 hs->sc_flags |= HPIBF_IO;
367 if (timo)
368 hs->sc_flags |= HPIBF_TIMO;
369 if (rw == B_READ)
370 hs->sc_flags |= HPIBF_READ;
371 #ifdef DEBUG
372 else if (hs->sc_flags & HPIBF_READ) {
373 printf("%s: HPIBF_READ still set\n", __func__);
374 hs->sc_flags &= ~HPIBF_READ;
376 #endif
377 hs->sc_count = count;
378 hs->sc_addr = addr;
379 #ifdef DEBUG
380 /* fhpibtransfer[unit]++; XXX */
381 #endif
382 if ((hs->sc_flags & HPIBF_DMA16) &&
383 ((int)addr & 1) == 0 && count && (count & 1) == 0
384 #ifdef DEBUG
385 && doworddma
386 #endif
388 #ifdef DEBUG
389 /* fhpibworddma[unit]++; XXX */
390 #endif
391 flags |= DMAGO_WORD;
392 hd->hpib_latch = 0;
394 #ifdef DEBUG
395 if (dopriodma)
396 flags |= DMAGO_PRI;
397 #endif
398 if (hs->sc_flags & HPIBF_READ) {
399 sc->sc_cmd = CT_REN | CT_8BIT;
400 hs->sc_curcnt = count;
401 dmago(hs->sc_dq->dq_chan, addr, count, flags|DMAGO_READ);
402 if (fhpibrecv(hs, slave, sec, 0, 0) < 0) {
403 #ifdef DEBUG
404 printf("%s: recv failed, retrying...\n", __func__);
405 #endif
406 (void)fhpibrecv(hs, slave, sec, 0, 0);
408 i = hd->hpib_cmd;
409 hd->hpib_cmd = sc->sc_cmd;
410 hd->hpib_ie = IDS_DMA(hs->sc_dq->dq_chan) |
411 ((flags & DMAGO_WORD) ? IDS_WDMA : 0);
412 return;
414 sc->sc_cmd = CT_REN | CT_8BIT | CT_FIFOSEL;
415 if (count < hpibdmathresh) {
416 #ifdef DEBUG
417 /* fhpibnondma[unit]++; XXX */
418 if (flags & DMAGO_WORD)
419 /* fhpibworddma[unit]--; XXX */ ;
420 #endif
421 hs->sc_curcnt = count;
422 (void) fhpibsend(hs, slave, sec, addr, count);
423 fhpibdone(hs);
424 return;
426 count -= (flags & DMAGO_WORD) ? 2 : 1;
427 hs->sc_curcnt = count;
428 dmago(hs->sc_dq->dq_chan, addr, count, flags);
429 if (fhpibsend(hs, slave, sec, 0, 0) < 0) {
430 #ifdef DEBUG
431 printf("%s: send failed, retrying...\n", __func__);
432 #endif
433 (void)fhpibsend(hs, slave, sec, 0, 0);
435 i = hd->hpib_cmd;
436 hd->hpib_cmd = sc->sc_cmd;
437 hd->hpib_ie = IDS_DMA(hs->sc_dq->dq_chan) | IDS_WRITE |
438 ((flags & DMAGO_WORD) ? IDS_WDMA : 0);
442 * A DMA read can finish but the device can still be waiting (MAG-tape
443 * with more data than we're waiting for). This timeout routine
444 * takes care of that. Somehow, the thing gets hosed. For now, since
445 * this should be a very rare occurence, we RESET it.
447 static void
448 fhpibdmadone(void *arg)
450 struct hpibbus_softc *hs = arg;
451 struct fhpib_softc *sc = device_private(device_parent(hs->sc_dev));
452 int s = splbio();
454 if (hs->sc_flags & HPIBF_IO) {
455 struct fhpibdevice *hd = sc->sc_regs;
456 struct hpibqueue *hq;
458 hd->hpib_imask = 0;
459 hd->hpib_cid = 0xFF;
460 DELAY(100);
461 hd->hpib_cmd = CT_8BIT;
462 hd->hpib_ar = AR_ARONC;
463 fhpibifc(hd);
464 hd->hpib_ie = IDS_IE;
465 hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
466 dmafree(hs->sc_dq);
468 hq = TAILQ_FIRST(&hs->sc_queue);
469 (hq->hq_intr)(hq->hq_softc);
471 splx(s);
474 static void
475 fhpibdone(struct hpibbus_softc *hs)
477 struct fhpib_softc *sc = device_private(device_parent(hs->sc_dev));
478 struct fhpibdevice *hd = sc->sc_regs;
479 char *addr;
480 int cnt;
482 cnt = hs->sc_curcnt;
483 hs->sc_addr += cnt;
484 hs->sc_count -= cnt;
485 #ifdef DEBUG
486 if ((fhpibdebug & FDB_DMA) &&
487 fhpibdebugunit == device_unit(sc->sc_dev))
488 printf("%s: addr %p cnt %d\n",
489 __func__, hs->sc_addr, hs->sc_count);
490 #endif
491 if (hs->sc_flags & HPIBF_READ) {
492 hd->hpib_imask = IM_IDLE | IM_BYTE;
493 if (hs->sc_flags & HPIBF_TIMO)
494 callout_reset(&sc->sc_dmadone_ch, hz >> 2,
495 fhpibdmadone, hs);
496 } else {
497 cnt = hs->sc_count;
498 if (cnt) {
499 addr = hs->sc_addr;
500 hd->hpib_imask = IM_IDLE | IM_ROOM;
501 FHPIBWAIT(hd, IM_IDLE);
502 hd->hpib_stat = ST_WRITE;
503 while (--cnt) {
504 hd->hpib_data = *addr++;
505 FHPIBWAIT(hd, IM_ROOM);
507 hd->hpib_stat = ST_EOI;
508 hd->hpib_data = *addr;
510 hd->hpib_imask = IM_IDLE;
512 hs->sc_flags |= HPIBF_DONE;
513 hd->hpib_stat = ST_IENAB;
514 hd->hpib_ie = IDS_IE;
517 static int
518 fhpibintr(void *arg)
520 struct fhpib_softc *sc = arg;
521 struct hpibbus_softc *hs = sc->sc_hpibbus;
522 struct fhpibdevice *hd = sc->sc_regs;
523 struct hpibqueue *hq;
524 int stat0;
526 stat0 = hd->hpib_ids;
527 if ((stat0 & (IDS_IE|IDS_IR)) != (IDS_IE|IDS_IR)) {
528 #ifdef DEBUG
529 if ((fhpibdebug & FDB_FAIL) && (stat0 & IDS_IR) &&
530 (hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) != HPIBF_IO)
531 printf("%s: fhpibintr: bad status %x\n",
532 device_xname(sc->sc_dev), stat0);
533 /* fhpibbadint[0]++; XXX */
534 #endif
535 return 0;
537 if ((hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) == HPIBF_IO) {
538 #ifdef DEBUG
539 /* fhpibbadint[1]++; XXX */
540 #endif
541 return 0;
543 #ifdef DEBUG
544 if ((fhpibdebug & FDB_DMA) &&
545 fhpibdebugunit == device_unit(sc->sc_dev))
546 printf("%s: flags %x\n", __func__, hs->sc_flags);
547 #endif
548 hq = TAILQ_FIRST(&hs->sc_queue);
549 if (hs->sc_flags & HPIBF_IO) {
550 if (hs->sc_flags & HPIBF_TIMO)
551 callout_stop(&sc->sc_dmadone_ch);
552 stat0 = hd->hpib_cmd;
553 hd->hpib_cmd = sc->sc_cmd & ~CT_8BIT;
554 hd->hpib_stat = 0;
555 hd->hpib_cmd = CT_REN | CT_8BIT;
556 stat0 = hd->hpib_intr;
557 hd->hpib_imask = 0;
558 hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
559 dmafree(hs->sc_dq);
560 (hq->hq_intr)(hq->hq_softc);
561 } else if (hs->sc_flags & HPIBF_PPOLL) {
562 stat0 = hd->hpib_intr;
563 #ifdef DEBUG
564 if ((fhpibdebug & FDB_FAIL) &&
565 doppollint && (stat0 & IM_PPRESP) == 0)
566 printf("%s: fhpibintr: bad intr reg %x\n",
567 device_xname(sc->sc_dev), stat0);
568 #endif
569 hd->hpib_stat = 0;
570 hd->hpib_imask = 0;
571 #ifdef DEBUG
572 stat0 = fhpibppoll(hs);
573 if ((fhpibdebug & FDB_PPOLL) &&
574 fhpibdebugunit == device_unit(sc->sc_dev))
575 printf("%s: got PPOLL status %x\n", __func__, stat0);
576 if ((stat0 & (0x80 >> hq->hq_slave)) == 0) {
578 * XXX give it another shot (68040)
580 /* fhpibppollfail[unit]++; XXX */
581 DELAY(fhpibppolldelay);
582 stat0 = fhpibppoll(hs);
583 if ((stat0 & (0x80 >> hq->hq_slave)) == 0 &&
584 (fhpibdebug & FDB_PPOLL) &&
585 fhpibdebugunit == device_unit(sc->sc_dev))
586 printf("%s: PPOLL: unit %d slave %d stat %x\n",
587 __func__, device_unit(sc->sc_dev),
588 hq->hq_slave, stat0);
590 #endif
591 hs->sc_flags &= ~HPIBF_PPOLL;
592 (hq->hq_intr)(hq->hq_softc);
594 return 1;
597 static int
598 fhpibppoll(struct hpibbus_softc *hs)
600 struct fhpib_softc *sc = device_private(device_parent(hs->sc_dev));
601 struct fhpibdevice *hd = sc->sc_regs;
602 int ppoll;
604 hd->hpib_stat = 0;
605 hd->hpib_psense = 0;
606 hd->hpib_pmask = 0xFF;
607 hd->hpib_imask = IM_PPRESP | IM_PABORT;
608 DELAY(25);
609 hd->hpib_intr = IM_PABORT;
610 ppoll = hd->hpib_data;
611 if (hd->hpib_intr & IM_PABORT)
612 ppoll = 0;
613 hd->hpib_imask = 0;
614 hd->hpib_pmask = 0;
615 hd->hpib_stat = ST_IENAB;
616 return ppoll;
619 static int
620 fhpibwait(struct fhpibdevice *hd, int x)
622 int timo = hpibtimeout;
624 while ((hd->hpib_intr & x) == 0 && --timo)
625 DELAY(1);
626 if (timo == 0) {
627 #ifdef DEBUG
628 if (fhpibdebug & FDB_FAIL)
629 printf("%s(%p, %x) timeout\n", __func__, hd, x);
630 #endif
631 return -1;
633 return 0;
637 * XXX: this will have to change if we ever allow more than one
638 * pending operation per HP-IB.
640 static void
641 fhpibppwatch(void *arg)
643 struct hpibbus_softc *hs = arg;
644 struct fhpib_softc *sc = device_private(device_parent(hs->sc_dev));
645 struct fhpibdevice *hd = sc->sc_regs;
646 int slave;
648 if ((hs->sc_flags & HPIBF_PPOLL) == 0)
649 return;
650 slave = (0x80 >> TAILQ_FIRST(&hs->sc_queue)->hq_slave);
651 #ifdef DEBUG
652 if (!doppollint) {
653 if (fhpibppoll(hs) & slave) {
654 hd->hpib_stat = ST_IENAB;
655 hd->hpib_imask = IM_IDLE | IM_ROOM;
656 } else
657 callout_reset(&sc->sc_ppwatch_ch, 1, fhpibppwatch, sc);
658 return;
660 if ((fhpibdebug & FDB_PPOLL) &&
661 device_unit(sc->sc_dev) == fhpibdebugunit)
662 printf("%s: sense request on %s\n",
663 __func__, device_xname(sc->sc_dev));
664 #endif
665 hd->hpib_psense = ~slave;
666 hd->hpib_pmask = slave;
667 hd->hpib_stat = ST_IENAB;
668 hd->hpib_imask = IM_PPRESP | IM_PABORT;
669 hd->hpib_ie = IDS_IE;