* Copyright (c) 1982, 1990 The Regents of the University of California.
* %sccs.include.redist.c%
* @(#)fhpib.c 7.3 (Berkeley) %G%
* Inline version of fhpibwait to be used in places where
* we don't worry about getting hung.
#define FHPIBWAIT(hd, m) while (((hd)->hpib_intr & (m)) == 0) DELAY(1)
int dopriodma
= 0; /* use high priority DMA */
int doworddma
= 1; /* non-zero if we should attempt word dma */
int doppollint
= 1; /* use ppoll interrupts instead of watchdog */
long fhpibbadint
[2] = { 0 };
long fhpibtransfer
[NHPIB
] = { 0 };
long fhpibnondma
[NHPIB
] = { 0 };
long fhpibworddma
[NHPIB
] = { 0 };
register struct hp_ctlr
*hc
;
register struct hpib_softc
*hs
= &hpib_softc
[hc
->hp_unit
];
register struct fhpibdevice
*hd
= (struct fhpibdevice
*)hc
->hp_addr
;
if (hd
->hpib_cid
!= HPIBC
)
hc
->hp_ipl
= HPIB_IPL(hd
->hpib_ids
);
register struct hpib_softc
*hs
= &hpib_softc
[unit
];
register struct fhpibdevice
*hd
;
hd
= (struct fhpibdevice
*)hs
->sc_hc
->hp_addr
;
* See if we can do word dma.
* If so, we should be able to write and read back the appropos bit.
if (hd
->hpib_ie
& IDS_WDMA
) {
hd
->hpib_ie
&= ~IDS_WDMA
;
hs
->sc_flags
|= HPIBF_DMA16
;
if (fhpibdebug
& FDB_DMA
)
printf("fhpibtype: unit %d has word dma\n", unit
);
register struct fhpibdevice
*hd
;
hd
->hpib_cmd
|= CT_INITFIFO
;
fhpibsend(unit
, slave
, sec
, addr
, origcnt
)
register struct hpib_softc
*hs
= &hpib_softc
[unit
];
register struct fhpibdevice
*hd
;
register int cnt
= origcnt
;
hd
= (struct fhpibdevice
*)hs
->sc_hc
->hp_addr
;
hd
->hpib_imask
= IM_IDLE
| IM_ROOM
;
if (fhpibwait(hd
, IM_IDLE
) < 0)
hd
->hpib_data
= C_TAG
+ hs
->sc_ba
;
hd
->hpib_data
= C_LAG
+ slave
;
hd
->hpib_data
= C_SCG
+ sec
;
if (fhpibwait(hd
, IM_IDLE
) < 0)
hd
->hpib_stat
= ST_WRITE
;
while ((hd
->hpib_intr
& IM_ROOM
) == 0) {
/* XXX: HP-UX claims bug with CS80 transparent messages */
(void) fhpibwait(hd
, IM_IDLE
);
if (fhpibdebug
& FDB_FAIL
) {
printf("hpib%d: fhpibsend failed: slave %d, sec %x, ",
printf("sent %d of %d bytes\n", origcnt
-cnt
-1, origcnt
);
return(origcnt
- cnt
- 1);
fhpibrecv(unit
, slave
, sec
, addr
, origcnt
)
register struct hpib_softc
*hs
= &hpib_softc
[unit
];
register struct fhpibdevice
*hd
;
register int cnt
= origcnt
;
hd
= (struct fhpibdevice
*)hs
->sc_hc
->hp_addr
;
hd
->hpib_imask
= IM_IDLE
| IM_ROOM
| IM_BYTE
;
if (fhpibwait(hd
, IM_IDLE
) < 0)
hd
->hpib_data
= C_LAG
+ hs
->sc_ba
;
hd
->hpib_data
= C_TAG
+ slave
;
hd
->hpib_data
= C_SCG
+ sec
;
if (fhpibwait(hd
, IM_IDLE
) < 0)
hd
->hpib_stat
= ST_READ0
;
while ((hd
->hpib_intr
& IM_BYTE
) == 0) {
hd
->hpib_data
= (slave
== 31) ? C_UNA
: C_UNT
;
(void) fhpibwait(hd
, IM_IDLE
);
if (fhpibdebug
& FDB_FAIL
) {
printf("hpib%d: fhpibrecv failed: slave %d, sec %x, ",
printf("got %d of %d bytes\n", origcnt
-cnt
-1, origcnt
);
return(origcnt
- cnt
- 1);
fhpibgo(unit
, slave
, sec
, addr
, count
, rw
)
register struct hpib_softc
*hs
= &hpib_softc
[unit
];
register struct fhpibdevice
*hd
;
hd
= (struct fhpibdevice
*)hs
->sc_hc
->hp_addr
;
hs
->sc_flags
|= HPIBF_IO
;
hs
->sc_flags
|= HPIBF_READ
;
else if (hs
->sc_flags
& HPIBF_READ
) {
printf("fhpibgo: HPIBF_READ still set\n");
hs
->sc_flags
&= ~HPIBF_READ
;
if ((hs
->sc_flags
& HPIBF_DMA16
) &&
((int)addr
& 1) == 0 && count
&& (count
& 1) == 0
if (hs
->sc_flags
& HPIBF_READ
) {
fhpibcmd
[unit
] = CT_REN
| CT_8BIT
;
dmago(hs
->sc_dq
.dq_ctlr
, addr
, count
, flags
|DMAGO_READ
);
if (fhpibrecv(unit
, slave
, sec
, 0, 0) < 0) {
printf("fhpibgo: recv failed, retrying...\n");
(void) fhpibrecv(unit
, slave
, sec
, 0, 0);
hd
->hpib_cmd
= fhpibcmd
[unit
];
hd
->hpib_ie
= IDS_DMA(hs
->sc_dq
.dq_ctlr
) |
((flags
& DMAGO_WORD
) ? IDS_WDMA
: 0);
fhpibcmd
[unit
] = CT_REN
| CT_8BIT
| CT_FIFOSEL
;
if (count
< hpibdmathresh
) {
(void) fhpibsend(unit
, slave
, sec
, addr
, count
);
count
-= (flags
& DMAGO_WORD
) ? 2 : 1;
dmago(hs
->sc_dq
.dq_ctlr
, addr
, count
, flags
);
if (fhpibsend(unit
, slave
, sec
, 0, 0) < 0) {
printf("fhpibgo: send failed, retrying...\n");
(void) fhpibsend(unit
, slave
, sec
, 0, 0);
hd
->hpib_cmd
= fhpibcmd
[unit
];
hd
->hpib_ie
= IDS_DMA(hs
->sc_dq
.dq_ctlr
) | IDS_WRITE
|
((flags
& DMAGO_WORD
) ? IDS_WDMA
: 0);
register struct hpib_softc
*hs
= &hpib_softc
[unit
];
register struct fhpibdevice
*hd
;
hd
= (struct fhpibdevice
*)hs
->sc_hc
->hp_addr
;
if ((fhpibdebug
& FDB_DMA
) && fhpibdebugunit
== unit
)
printf("fhpibdone: addr %x cnt %d\n",
hs
->sc_addr
, hs
->sc_count
);
if (hs
->sc_flags
& HPIBF_READ
)
hd
->hpib_imask
= IM_IDLE
| IM_BYTE
;
hd
->hpib_imask
= IM_IDLE
| IM_ROOM
;
hd
->hpib_stat
= ST_WRITE
;
hd
->hpib_imask
= IM_IDLE
;
hs
->sc_flags
|= HPIBF_DONE
;
hd
->hpib_stat
= ST_IENAB
;
register struct hpib_softc
*hs
= &hpib_softc
[unit
];
register struct fhpibdevice
*hd
;
register struct devqueue
*dq
;
hd
= (struct fhpibdevice
*)hs
->sc_hc
->hp_addr
;
if ((stat0
& (IDS_IE
|IDS_IR
)) != (IDS_IE
|IDS_IR
)) {
if ((fhpibdebug
& FDB_FAIL
) && (stat0
& IDS_IR
) &&
(hs
->sc_flags
& (HPIBF_IO
|HPIBF_DONE
)) != HPIBF_IO
)
printf("hpib%d: fhpibintr: bad status %x\n",
if ((hs
->sc_flags
& (HPIBF_IO
|HPIBF_DONE
)) == HPIBF_IO
) {
if ((fhpibdebug
& FDB_DMA
) && fhpibdebugunit
== unit
)
printf("fhpibintr: flags %x\n", hs
->sc_flags
);
if (hs
->sc_flags
& HPIBF_IO
) {
hd
->hpib_cmd
= fhpibcmd
[unit
] & ~CT_8BIT
;
hd
->hpib_cmd
= CT_REN
| CT_8BIT
;
hs
->sc_flags
&= ~(HPIBF_DONE
|HPIBF_IO
|HPIBF_READ
);
(dq
->dq_driver
->d_intr
)(dq
->dq_unit
);
} else if (hs
->sc_flags
& HPIBF_PPOLL
) {
if ((fhpibdebug
& FDB_FAIL
) &&
doppollint
&& (stat0
& IM_PPRESP
) == 0)
printf("hpib%d: fhpibintr: bad intr reg %x\n",
stat0
= fhpibppoll(unit
);
if ((fhpibdebug
& FDB_PPOLL
) && unit
== fhpibdebugunit
)
printf("fhpibintr: got PPOLL status %x\n", stat0
);
if ((stat0
& (0x80 >> dq
->dq_slave
)) == 0) {
printf("fhpibintr: PPOLL: unit %d slave %d stat %x\n",
unit
, dq
->dq_slave
, stat0
);
hs
->sc_flags
&= ~HPIBF_PPOLL
;
(dq
->dq_driver
->d_intr
)(dq
->dq_unit
);
register struct fhpibdevice
*hd
;
hd
= (struct fhpibdevice
*)hpib_softc
[unit
].sc_hc
->hp_addr
;
hd
->hpib_imask
= IM_PPRESP
| IM_PABORT
;
hd
->hpib_intr
= IM_PABORT
;
if (hd
->hpib_intr
& IM_PABORT
)
hd
->hpib_stat
= ST_IENAB
;
register struct fhpibdevice
*hd
;
register int timo
= hpibtimeout
;
while ((hd
->hpib_intr
& x
) == 0 && --timo
)
if (fhpibdebug
& FDB_FAIL
)
printf("fhpibwait(%x, %x) timeout\n", hd
, x
);
* XXX: this will have to change if we every allow more than one
* pending operation per HP-IB.
register struct hpib_softc
*hs
= &hpib_softc
[unit
];
register struct fhpibdevice
*hd
;
if ((hs
->sc_flags
& HPIBF_PPOLL
) == 0)
hd
= (struct fhpibdevice
*)hs
->sc_hc
->hp_addr
;
slave
= (0x80 >> hs
->sc_sq
.dq_forw
->dq_slave
);
if (fhpibppoll(unit
) & slave
) {
hd
->hpib_stat
= ST_IENAB
;
hd
->hpib_imask
= IM_IDLE
| IM_ROOM
;
timeout(fhpibppwatch
, unit
, 1);
if ((fhpibdebug
& FDB_PPOLL
) && unit
== fhpibdebugunit
)
printf("fhpibppwatch: sense request on %d\n", unit
);
hd
->hpib_psense
= ~slave
;
hd
->hpib_stat
= ST_IENAB
;
hd
->hpib_imask
= IM_PPRESP
| IM_PABORT
;