1 /* $NetBSD: fhpib.c,v 1.38 2008/03/29 06:47:07 tsutsui Exp $ */
4 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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
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
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>
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)
95 int fhpibdebugunit
= -1;
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;
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,
119 static void fhpibdone(struct hpibbus_softc
*);
120 static int fhpibintr(void *);
123 * Our controller ops structure.
125 static struct hpib_controller fhpib_controller
= {
137 device_t sc_dev
; /* generic device glue */
138 struct fhpibdevice
*sc_regs
; /* device registers */
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
);
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
)
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
;
171 if (bus_space_map(da
->da_bst
, da
->da_addr
, da
->da_size
, 0, &bsh
)) {
172 aprint_error(": can't map registers\n");
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 */
188 ha
.ha_softcpp
= &sc
->sc_hpibbus
; /* XXX */
189 (void)config_found(self
, &ha
, hpibdevprint
);
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
;
200 hd
->hpib_cmd
= CT_8BIT
;
201 hd
->hpib_ar
= AR_ARONC
;
203 hd
->hpib_ie
= IDS_IE
;
204 hd
->hpib_data
= C_DCL
;
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
;
215 if (fhpibdebug
& FDB_DMA
)
216 printf("fhpibtype: %s has word DMA\n",
217 device_xname(sc
->sc_dev
));
223 fhpibifc(struct fhpibdevice
*hd
)
226 hd
->hpib_cmd
|= CT_IFC
;
227 hd
->hpib_cmd
|= CT_INITFIFO
;
229 hd
->hpib_cmd
&= ~CT_IFC
;
230 hd
->hpib_cmd
|= CT_REN
;
231 hd
->hpib_stat
= ST_ATN
;
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
;
244 hd
->hpib_imask
= IM_IDLE
| IM_ROOM
;
245 if (fhpibwait(hd
, IM_IDLE
) < 0)
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
;
252 if (sec
== -2) /* selected device clear KLUDGE */
253 hd
->hpib_data
= C_SDC
;
255 hd
->hpib_data
= C_SCG
+ sec
;
256 if (fhpibwait(hd
, IM_IDLE
) < 0)
259 hd
->hpib_stat
= ST_WRITE
;
261 hd
->hpib_data
= *addr
++;
263 while ((hd
->hpib_intr
& IM_ROOM
) == 0) {
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 */
276 hd
->hpib_data
= C_UNL
;
277 (void) fhpibwait(hd
, IM_IDLE
);
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
);
292 return origcnt
- cnt
- 1;
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
;
305 * Slave < 0 implies continuation of a previous receive
306 * that probably timed out.
310 hd
->hpib_imask
= IM_IDLE
| IM_ROOM
| IM_BYTE
;
311 if (fhpibwait(hd
, IM_IDLE
) < 0)
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
;
318 hd
->hpib_data
= C_SCG
+ sec
;
319 if (fhpibwait(hd
, IM_IDLE
) < 0)
321 hd
->hpib_stat
= ST_READ0
;
327 while ((hd
->hpib_intr
& IM_BYTE
) == 0) {
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
);
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
);
353 return origcnt
- cnt
- 1;
357 fhpibgo(struct hpibbus_softc
*hs
, int slave
, int sec
, void *ptr
, int count
,
360 struct fhpib_softc
*sc
= device_private(device_parent(hs
->sc_dev
));
361 struct fhpibdevice
*hd
= sc
->sc_regs
;
366 hs
->sc_flags
|= HPIBF_IO
;
368 hs
->sc_flags
|= HPIBF_TIMO
;
370 hs
->sc_flags
|= HPIBF_READ
;
372 else if (hs
->sc_flags
& HPIBF_READ
) {
373 printf("%s: HPIBF_READ still set\n", __func__
);
374 hs
->sc_flags
&= ~HPIBF_READ
;
377 hs
->sc_count
= count
;
380 /* fhpibtransfer[unit]++; XXX */
382 if ((hs
->sc_flags
& HPIBF_DMA16
) &&
383 ((int)addr
& 1) == 0 && count
&& (count
& 1) == 0
389 /* fhpibworddma[unit]++; XXX */
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) {
404 printf("%s: recv failed, retrying...\n", __func__
);
406 (void)fhpibrecv(hs
, slave
, sec
, 0, 0);
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);
414 sc
->sc_cmd
= CT_REN
| CT_8BIT
| CT_FIFOSEL
;
415 if (count
< hpibdmathresh
) {
417 /* fhpibnondma[unit]++; XXX */
418 if (flags
& DMAGO_WORD
)
419 /* fhpibworddma[unit]--; XXX */ ;
421 hs
->sc_curcnt
= count
;
422 (void) fhpibsend(hs
, slave
, sec
, addr
, count
);
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) {
431 printf("%s: send failed, retrying...\n", __func__
);
433 (void)fhpibsend(hs
, slave
, sec
, 0, 0);
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.
448 fhpibdmadone(void *arg
)
450 struct hpibbus_softc
*hs
= arg
;
451 struct fhpib_softc
*sc
= device_private(device_parent(hs
->sc_dev
));
454 if (hs
->sc_flags
& HPIBF_IO
) {
455 struct fhpibdevice
*hd
= sc
->sc_regs
;
456 struct hpibqueue
*hq
;
461 hd
->hpib_cmd
= CT_8BIT
;
462 hd
->hpib_ar
= AR_ARONC
;
464 hd
->hpib_ie
= IDS_IE
;
465 hs
->sc_flags
&= ~(HPIBF_DONE
|HPIBF_IO
|HPIBF_READ
|HPIBF_TIMO
);
468 hq
= TAILQ_FIRST(&hs
->sc_queue
);
469 (hq
->hq_intr
)(hq
->hq_softc
);
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
;
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
);
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,
500 hd
->hpib_imask
= IM_IDLE
| IM_ROOM
;
501 FHPIBWAIT(hd
, IM_IDLE
);
502 hd
->hpib_stat
= ST_WRITE
;
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
;
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
;
526 stat0
= hd
->hpib_ids
;
527 if ((stat0
& (IDS_IE
|IDS_IR
)) != (IDS_IE
|IDS_IR
)) {
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 */
537 if ((hs
->sc_flags
& (HPIBF_IO
|HPIBF_DONE
)) == HPIBF_IO
) {
539 /* fhpibbadint[1]++; XXX */
544 if ((fhpibdebug
& FDB_DMA
) &&
545 fhpibdebugunit
== device_unit(sc
->sc_dev
))
546 printf("%s: flags %x\n", __func__
, hs
->sc_flags
);
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
;
555 hd
->hpib_cmd
= CT_REN
| CT_8BIT
;
556 stat0
= hd
->hpib_intr
;
558 hs
->sc_flags
&= ~(HPIBF_DONE
|HPIBF_IO
|HPIBF_READ
|HPIBF_TIMO
);
560 (hq
->hq_intr
)(hq
->hq_softc
);
561 } else if (hs
->sc_flags
& HPIBF_PPOLL
) {
562 stat0
= hd
->hpib_intr
;
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
);
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
);
591 hs
->sc_flags
&= ~HPIBF_PPOLL
;
592 (hq
->hq_intr
)(hq
->hq_softc
);
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
;
606 hd
->hpib_pmask
= 0xFF;
607 hd
->hpib_imask
= IM_PPRESP
| IM_PABORT
;
609 hd
->hpib_intr
= IM_PABORT
;
610 ppoll
= hd
->hpib_data
;
611 if (hd
->hpib_intr
& IM_PABORT
)
615 hd
->hpib_stat
= ST_IENAB
;
620 fhpibwait(struct fhpibdevice
*hd
, int x
)
622 int timo
= hpibtimeout
;
624 while ((hd
->hpib_intr
& x
) == 0 && --timo
)
628 if (fhpibdebug
& FDB_FAIL
)
629 printf("%s(%p, %x) timeout\n", __func__
, hd
, x
);
637 * XXX: this will have to change if we ever allow more than one
638 * pending operation per HP-IB.
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
;
648 if ((hs
->sc_flags
& HPIBF_PPOLL
) == 0)
650 slave
= (0x80 >> TAILQ_FIRST(&hs
->sc_queue
)->hq_slave
);
653 if (fhpibppoll(hs
) & slave
) {
654 hd
->hpib_stat
= ST_IENAB
;
655 hd
->hpib_imask
= IM_IDLE
| IM_ROOM
;
657 callout_reset(&sc
->sc_ppwatch_ch
, 1, fhpibppwatch
, sc
);
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
));
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
;