1 /* $NetBSD: fhpib.c,v 1.44 2024/01/16 05:48:28 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 *
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.
30 */
31
32 /*
33 * Copyright (c) 1982, 1990, 1993
34 * The Regents of the University of California. All rights reserved.
35 *
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.
47 *
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.
59 *
60 * @(#)fhpib.c 8.2 (Berkeley) 1/12/94
61 */
62
63 /*
64 * 98625A/B HPIB driver
65 */
66
67 #include <sys/cdefs.h>
68 __KERNEL_RCSID(0, "$NetBSD: fhpib.c,v 1.44 2024/01/16 05:48:28 thorpej Exp $");
69
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>
76
77 #include <machine/autoconf.h>
78 #include <machine/intr.h>
79
80 #include <hp300/dev/diovar.h>
81 #include <hp300/dev/diodevs.h>
82
83 #include <hp300/dev/dmavar.h>
84
85 #include <hp300/dev/fhpibreg.h>
86 #include <hp300/dev/hpibvar.h>
87
88 /*
89 * Inline version of fhpibwait to be used in places where
90 * we don't worry about getting hung.
91 */
92 #define FHPIBWAIT(hd, m) while (((hd)->hpib_intr & (m)) == 0) DELAY(1)
93
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
101
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
107
108 static void fhpibifc(struct fhpibdevice *);
109 static void fhpibdmadone(void *);
110 static int fhpibwait(struct fhpibdevice *, int);
111
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 *);
121
122 /*
123 * Our controller ops structure.
124 */
125 static struct hpib_controller fhpib_controller = {
126 fhpibreset,
127 fhpibsend,
128 fhpibrecv,
129 fhpibppoll,
130 fhpibppwatch,
131 fhpibgo,
132 fhpibdone,
133 fhpibintr
134 };
135
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;
143 };
144
145 static int fhpibmatch(device_t, cfdata_t, void *);
146 static void fhpibattach(device_t, device_t, void *);
147
148 CFATTACH_DECL_NEW(fhpib, sizeof(struct fhpib_softc),
149 fhpibmatch, fhpibattach, NULL, NULL);
150
151 static int
fhpibmatch(device_t parent,cfdata_t cf,void * aux)152 fhpibmatch(device_t parent, cfdata_t cf, void *aux)
153 {
154 struct dio_attach_args *da = aux;
155
156 if (da->da_id == DIO_DEVICE_ID_FHPIB)
157 return 1;
158
159 return 0;
160 }
161
162 static void
fhpibattach(device_t parent,device_t self,void * aux)163 fhpibattach(device_t parent, device_t self, void *aux)
164 {
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;
169
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;
174 }
175 sc->sc_regs = bus_space_vaddr(da->da_bst, bsh);
176
177 aprint_normal(": %s\n", DIO_DEVICE_DESC_FHPIB);
178
179 /* Establish the interrupt handler. */
180 (void)dio_intr_establish(fhpibintr, sc, da->da_ipl, ISRPRI_BIO);
181
182 callout_init(&sc->sc_dmadone_ch, 0);
183 callout_init(&sc->sc_ppwatch_ch, 0);
184
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, CFARGS_NONE);
190 }
191
192 static void
fhpibreset(struct hpibbus_softc * hs)193 fhpibreset(struct hpibbus_softc *hs)
194 {
195 struct fhpib_softc *sc = device_private(device_parent(hs->sc_dev));
196 struct fhpibdevice *hd = sc->sc_regs;
197
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);
206 /*
207 * See if we can do word DMA.
208 * If so, we should be able to write and read back the appropos bit.
209 */
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
219 }
220 }
221
222 static void
fhpibifc(struct fhpibdevice * hd)223 fhpibifc(struct fhpibdevice *hd)
224 {
225
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;
232 }
233
234 static int
fhpibsend(struct hpibbus_softc * hs,int slave,int sec,void * ptr,int origcnt)235 fhpibsend(struct hpibbus_softc *hs, int slave, int sec, void *ptr, int origcnt)
236 {
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;
242
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);
267 }
268 }
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);
278 }
279 hd->hpib_imask = 0;
280 return origcnt;
281
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);
290 }
291 #endif
292 return origcnt - cnt - 1;
293 }
294
295 static int
fhpibrecv(struct hpibbus_softc * hs,int slave,int sec,void * ptr,int origcnt)296 fhpibrecv(struct hpibbus_softc *hs, int slave, int sec, void *ptr, int origcnt)
297 {
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;
303
304 /*
305 * Slave < 0 implies continuation of a previous receive
306 * that probably timed out.
307 */
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;
323 }
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);
331 }
332 *addr++ = hd->hpib_data;
333 }
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);
338 }
339 hd->hpib_imask = 0;
340 return origcnt;
341
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);
351 }
352 #endif
353 return origcnt - cnt - 1;
354 }
355
356 static void
fhpibgo(struct hpibbus_softc * hs,int slave,int sec,void * ptr,int count,int rw,int timo)357 fhpibgo(struct hpibbus_softc *hs, int slave, int sec, void *ptr, int count,
358 int rw, int timo)
359 {
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;
365
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;
375 }
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
387 ) {
388 #ifdef DEBUG
389 /* fhpibworddma[unit]++; XXX */
390 #endif
391 flags |= DMAGO_WORD;
392 hd->hpib_latch = 0;
393 }
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);
407 }
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 __USE(i);
413 return;
414 }
415 sc->sc_cmd = CT_REN | CT_8BIT | CT_FIFOSEL;
416 if (count < hpibdmathresh) {
417 #ifdef DEBUG
418 /* fhpibnondma[unit]++; XXX */
419 if (flags & DMAGO_WORD)
420 /* fhpibworddma[unit]--; XXX */ ;
421 #endif
422 hs->sc_curcnt = count;
423 (void) fhpibsend(hs, slave, sec, addr, count);
424 fhpibdone(hs);
425 return;
426 }
427 count -= (flags & DMAGO_WORD) ? 2 : 1;
428 hs->sc_curcnt = count;
429 dmago(hs->sc_dq->dq_chan, addr, count, flags);
430 if (fhpibsend(hs, slave, sec, 0, 0) < 0) {
431 #ifdef DEBUG
432 printf("%s: send failed, retrying...\n", __func__);
433 #endif
434 (void)fhpibsend(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) | IDS_WRITE |
439 ((flags & DMAGO_WORD) ? IDS_WDMA : 0);
440 __USE(i);
441 }
442
443 /*
444 * A DMA read can finish but the device can still be waiting (MAG-tape
445 * with more data than we're waiting for). This timeout routine
446 * takes care of that. Somehow, the thing gets hosed. For now, since
447 * this should be a very rare occurrence, we RESET it.
448 */
449 static void
fhpibdmadone(void * arg)450 fhpibdmadone(void *arg)
451 {
452 struct hpibbus_softc *hs = arg;
453 struct fhpib_softc *sc = device_private(device_parent(hs->sc_dev));
454 int s = splbio();
455
456 if (hs->sc_flags & HPIBF_IO) {
457 struct fhpibdevice *hd = sc->sc_regs;
458 struct hpibqueue *hq;
459
460 hd->hpib_imask = 0;
461 hd->hpib_cid = 0xFF;
462 DELAY(100);
463 hd->hpib_cmd = CT_8BIT;
464 hd->hpib_ar = AR_ARONC;
465 fhpibifc(hd);
466 hd->hpib_ie = IDS_IE;
467 hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
468 dmafree(hs->sc_dq);
469
470 hq = TAILQ_FIRST(&hs->sc_queue);
471 (hq->hq_intr)(hq->hq_softc);
472 }
473 splx(s);
474 }
475
476 static void
fhpibdone(struct hpibbus_softc * hs)477 fhpibdone(struct hpibbus_softc *hs)
478 {
479 struct fhpib_softc *sc = device_private(device_parent(hs->sc_dev));
480 struct fhpibdevice *hd = sc->sc_regs;
481 char *addr;
482 int cnt;
483
484 cnt = hs->sc_curcnt;
485 hs->sc_addr += cnt;
486 hs->sc_count -= cnt;
487 #ifdef DEBUG
488 if ((fhpibdebug & FDB_DMA) &&
489 fhpibdebugunit == device_unit(sc->sc_dev))
490 printf("%s: addr %p cnt %d\n",
491 __func__, hs->sc_addr, hs->sc_count);
492 #endif
493 if (hs->sc_flags & HPIBF_READ) {
494 hd->hpib_imask = IM_IDLE | IM_BYTE;
495 if (hs->sc_flags & HPIBF_TIMO)
496 callout_reset(&sc->sc_dmadone_ch, hz >> 2,
497 fhpibdmadone, hs);
498 } else {
499 cnt = hs->sc_count;
500 if (cnt) {
501 addr = hs->sc_addr;
502 hd->hpib_imask = IM_IDLE | IM_ROOM;
503 FHPIBWAIT(hd, IM_IDLE);
504 hd->hpib_stat = ST_WRITE;
505 while (--cnt) {
506 hd->hpib_data = *addr++;
507 FHPIBWAIT(hd, IM_ROOM);
508 }
509 hd->hpib_stat = ST_EOI;
510 hd->hpib_data = *addr;
511 }
512 hd->hpib_imask = IM_IDLE;
513 }
514 hs->sc_flags |= HPIBF_DONE;
515 hd->hpib_stat = ST_IENAB;
516 hd->hpib_ie = IDS_IE;
517 }
518
519 static int
fhpibintr(void * arg)520 fhpibintr(void *arg)
521 {
522 struct fhpib_softc *sc = arg;
523 struct hpibbus_softc *hs = sc->sc_hpibbus;
524 struct fhpibdevice *hd = sc->sc_regs;
525 struct hpibqueue *hq;
526 int stat0;
527
528 stat0 = hd->hpib_ids;
529 if ((stat0 & (IDS_IE|IDS_IR)) != (IDS_IE|IDS_IR)) {
530 #ifdef DEBUG
531 if ((fhpibdebug & FDB_FAIL) && (stat0 & IDS_IR) &&
532 (hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) != HPIBF_IO)
533 printf("%s: fhpibintr: bad status %x\n",
534 device_xname(sc->sc_dev), stat0);
535 /* fhpibbadint[0]++; XXX */
536 #endif
537 return 0;
538 }
539 if ((hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) == HPIBF_IO) {
540 #ifdef DEBUG
541 /* fhpibbadint[1]++; XXX */
542 #endif
543 return 0;
544 }
545 #ifdef DEBUG
546 if ((fhpibdebug & FDB_DMA) &&
547 fhpibdebugunit == device_unit(sc->sc_dev))
548 printf("%s: flags %x\n", __func__, hs->sc_flags);
549 #endif
550 hq = TAILQ_FIRST(&hs->sc_queue);
551 if (hs->sc_flags & HPIBF_IO) {
552 if (hs->sc_flags & HPIBF_TIMO)
553 callout_stop(&sc->sc_dmadone_ch);
554 stat0 = hd->hpib_cmd;
555 hd->hpib_cmd = sc->sc_cmd & ~CT_8BIT;
556 hd->hpib_stat = 0;
557 hd->hpib_cmd = CT_REN | CT_8BIT;
558 stat0 = hd->hpib_intr;
559 hd->hpib_imask = 0;
560 hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
561 dmafree(hs->sc_dq);
562 (hq->hq_intr)(hq->hq_softc);
563 } else if (hs->sc_flags & HPIBF_PPOLL) {
564 stat0 = hd->hpib_intr;
565 #ifdef DEBUG
566 if ((fhpibdebug & FDB_FAIL) &&
567 doppollint && (stat0 & IM_PPRESP) == 0)
568 printf("%s: fhpibintr: bad intr reg %x\n",
569 device_xname(sc->sc_dev), stat0);
570 #endif
571 hd->hpib_stat = 0;
572 hd->hpib_imask = 0;
573 #ifdef DEBUG
574 stat0 = fhpibppoll(hs);
575 if ((fhpibdebug & FDB_PPOLL) &&
576 fhpibdebugunit == device_unit(sc->sc_dev))
577 printf("%s: got PPOLL status %x\n", __func__, stat0);
578 if ((stat0 & (0x80 >> hq->hq_slave)) == 0) {
579 /*
580 * XXX give it another shot (68040)
581 */
582 /* fhpibppollfail[unit]++; XXX */
583 DELAY(fhpibppolldelay);
584 stat0 = fhpibppoll(hs);
585 if ((stat0 & (0x80 >> hq->hq_slave)) == 0 &&
586 (fhpibdebug & FDB_PPOLL) &&
587 fhpibdebugunit == device_unit(sc->sc_dev))
588 printf("%s: PPOLL: unit %d slave %d stat %x\n",
589 __func__, device_unit(sc->sc_dev),
590 hq->hq_slave, stat0);
591 }
592 #endif
593 hs->sc_flags &= ~HPIBF_PPOLL;
594 (hq->hq_intr)(hq->hq_softc);
595 }
596 return 1;
597 }
598
599 static int
fhpibppoll(struct hpibbus_softc * hs)600 fhpibppoll(struct hpibbus_softc *hs)
601 {
602 struct fhpib_softc *sc = device_private(device_parent(hs->sc_dev));
603 struct fhpibdevice *hd = sc->sc_regs;
604 int ppoll;
605
606 hd->hpib_stat = 0;
607 hd->hpib_psense = 0;
608 hd->hpib_pmask = 0xFF;
609 hd->hpib_imask = IM_PPRESP | IM_PABORT;
610 DELAY(25);
611 hd->hpib_intr = IM_PABORT;
612 ppoll = hd->hpib_data;
613 if (hd->hpib_intr & IM_PABORT)
614 ppoll = 0;
615 hd->hpib_imask = 0;
616 hd->hpib_pmask = 0;
617 hd->hpib_stat = ST_IENAB;
618 return ppoll;
619 }
620
621 static int
fhpibwait(struct fhpibdevice * hd,int x)622 fhpibwait(struct fhpibdevice *hd, int x)
623 {
624 int timo = hpibtimeout;
625
626 while ((hd->hpib_intr & x) == 0 && --timo)
627 DELAY(1);
628 if (timo == 0) {
629 #ifdef DEBUG
630 if (fhpibdebug & FDB_FAIL)
631 printf("%s(%p, %x) timeout\n", __func__, hd, x);
632 #endif
633 return -1;
634 }
635 return 0;
636 }
637
638 /*
639 * XXX: this will have to change if we ever allow more than one
640 * pending operation per HP-IB.
641 */
642 static void
fhpibppwatch(void * arg)643 fhpibppwatch(void *arg)
644 {
645 struct hpibbus_softc *hs = arg;
646 struct fhpib_softc *sc = device_private(device_parent(hs->sc_dev));
647 struct fhpibdevice *hd = sc->sc_regs;
648 int slave;
649
650 if ((hs->sc_flags & HPIBF_PPOLL) == 0)
651 return;
652 slave = (0x80 >> TAILQ_FIRST(&hs->sc_queue)->hq_slave);
653 #ifdef DEBUG
654 if (!doppollint) {
655 if (fhpibppoll(hs) & slave) {
656 hd->hpib_stat = ST_IENAB;
657 hd->hpib_imask = IM_IDLE | IM_ROOM;
658 } else
659 callout_reset(&sc->sc_ppwatch_ch, 1, fhpibppwatch, sc);
660 return;
661 }
662 if ((fhpibdebug & FDB_PPOLL) &&
663 device_unit(sc->sc_dev) == fhpibdebugunit)
664 printf("%s: sense request on %s\n",
665 __func__, device_xname(sc->sc_dev));
666 #endif
667 hd->hpib_psense = ~slave;
668 hd->hpib_pmask = slave;
669 hd->hpib_stat = ST_IENAB;
670 hd->hpib_imask = IM_PPRESP | IM_PABORT;
671 hd->hpib_ie = IDS_IE;
672 }
673