141480Smckusick /*
263151Sbostic * Copyright (c) 1982, 1990, 1993
363151Sbostic * The Regents of the University of California. All rights reserved.
441480Smckusick *
541480Smckusick * %sccs.include.redist.c%
641480Smckusick *
7*65637Sbostic * @(#)nhpib.c 8.2 (Berkeley) 01/12/94
841480Smckusick */
941480Smckusick
1041480Smckusick /*
1141480Smckusick * Internal/98624 HPIB driver
1241480Smckusick */
1341480Smckusick #include "hpib.h"
1441480Smckusick #if NHPIB > 0
1541480Smckusick
1656507Sbostic #include <sys/param.h>
1756507Sbostic #include <sys/systm.h>
1856507Sbostic #include <sys/buf.h>
1945788Sbostic
2056507Sbostic #include <hp/dev/device.h>
2156507Sbostic #include <hp300/dev/nhpibreg.h>
2256507Sbostic #include <hp300/dev/hpibvar.h>
2356507Sbostic #include <hp300/dev/dmavar.h>
2441480Smckusick
nhpibtype(hc)2541480Smckusick nhpibtype(hc)
2641480Smckusick register struct hp_ctlr *hc;
2741480Smckusick {
2841480Smckusick register struct hpib_softc *hs = &hpib_softc[hc->hp_unit];
2941480Smckusick register struct nhpibdevice *hd = (struct nhpibdevice *)hc->hp_addr;
3041480Smckusick
3149305Shibler if (hc->hp_addr == internalhpib) {
3241480Smckusick hs->sc_type = HPIBA;
3341480Smckusick hs->sc_ba = HPIBA_BA;
3441480Smckusick hc->hp_ipl = HPIBA_IPL;
3541480Smckusick }
3641480Smckusick else if (hd->hpib_cid == HPIBB) {
3741480Smckusick hs->sc_type = HPIBB;
3841480Smckusick hs->sc_ba = hd->hpib_csa & CSA_BA;
3941480Smckusick hc->hp_ipl = HPIB_IPL(hd->hpib_ids);
4041480Smckusick }
4141480Smckusick else
4241480Smckusick return(0);
4341480Smckusick return(1);
4441480Smckusick }
4541480Smckusick
nhpibreset(unit)4641480Smckusick nhpibreset(unit)
47*65637Sbostic int unit;
4841480Smckusick {
4941480Smckusick register struct hpib_softc *hs = &hpib_softc[unit];
5041480Smckusick register struct nhpibdevice *hd;
5141480Smckusick
5241480Smckusick hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
5341480Smckusick hd->hpib_acr = AUX_SSWRST;
5441480Smckusick hd->hpib_ar = hs->sc_ba;
5541480Smckusick hd->hpib_lim = LIS_ERR;
5641480Smckusick hd->hpib_mim = 0;
5741480Smckusick hd->hpib_acr = AUX_CDAI;
5841480Smckusick hd->hpib_acr = AUX_CSHDW;
5941480Smckusick hd->hpib_acr = AUX_SSTD1;
6041480Smckusick hd->hpib_acr = AUX_SVSTD1;
6141480Smckusick hd->hpib_acr = AUX_CPP;
6241480Smckusick hd->hpib_acr = AUX_CHDFA;
6341480Smckusick hd->hpib_acr = AUX_CHDFE;
6441480Smckusick hd->hpib_acr = AUX_RHDF;
6541480Smckusick hd->hpib_acr = AUX_CSWRST;
6641480Smckusick nhpibifc(hd);
6741480Smckusick hd->hpib_ie = IDS_IE;
6841480Smckusick hd->hpib_data = C_DCL;
6941480Smckusick DELAY(100000);
7041480Smckusick }
7141480Smckusick
nhpibifc(hd)7241480Smckusick nhpibifc(hd)
7341480Smckusick register struct nhpibdevice *hd;
7441480Smckusick {
7541480Smckusick hd->hpib_acr = AUX_TCA;
7641480Smckusick hd->hpib_acr = AUX_CSRE;
7741480Smckusick hd->hpib_acr = AUX_SSIC;
7841480Smckusick DELAY(100);
7941480Smckusick hd->hpib_acr = AUX_CSIC;
8041480Smckusick hd->hpib_acr = AUX_SSRE;
8141480Smckusick }
8241480Smckusick
nhpibsend(unit,slave,sec,addr,origcnt)8345511Smckusick nhpibsend(unit, slave, sec, addr, origcnt)
84*65637Sbostic int unit, slave, sec, origcnt;
8541480Smckusick register char *addr;
8641480Smckusick {
8741480Smckusick register struct hpib_softc *hs = &hpib_softc[unit];
8841480Smckusick register struct nhpibdevice *hd;
8945511Smckusick register int cnt = origcnt;
9041480Smckusick
9141480Smckusick hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
9241480Smckusick hd->hpib_acr = AUX_TCA;
9341480Smckusick hd->hpib_data = C_UNL;
9445511Smckusick if (nhpibwait(hd, MIS_BO))
9545511Smckusick goto senderror;
9641480Smckusick hd->hpib_data = C_TAG + hs->sc_ba;
9741480Smckusick hd->hpib_acr = AUX_STON;
9845511Smckusick if (nhpibwait(hd, MIS_BO))
9945511Smckusick goto senderror;
10041480Smckusick hd->hpib_data = C_LAG + slave;
10145511Smckusick if (nhpibwait(hd, MIS_BO))
10245511Smckusick goto senderror;
10341480Smckusick if (sec != -1) {
10441480Smckusick hd->hpib_data = C_SCG + sec;
10545511Smckusick if (nhpibwait(hd, MIS_BO))
10645511Smckusick goto senderror;
10741480Smckusick }
10841480Smckusick hd->hpib_acr = AUX_GTS;
10941480Smckusick if (cnt) {
11045511Smckusick while (--cnt > 0) {
11141480Smckusick hd->hpib_data = *addr++;
11245511Smckusick if (nhpibwait(hd, MIS_BO))
11345511Smckusick goto senderror;
11441480Smckusick }
11541480Smckusick hd->hpib_acr = AUX_EOI;
11641480Smckusick hd->hpib_data = *addr;
11745511Smckusick if (nhpibwait(hd, MIS_BO))
11845511Smckusick goto senderror;
11945511Smckusick hd->hpib_acr = AUX_TCA;
12045511Smckusick #if 0
12145511Smckusick /*
12245511Smckusick * May be causing 345 disks to hang due to interference
12345511Smckusick * with PPOLL mechanism.
12445511Smckusick */
12545511Smckusick hd->hpib_data = C_UNL;
12645511Smckusick (void) nhpibwait(hd, MIS_BO);
12745511Smckusick #endif
12841480Smckusick }
12945511Smckusick return(origcnt);
13045511Smckusick senderror:
13145511Smckusick nhpibifc(hd);
13245511Smckusick return(origcnt - cnt - 1);
13341480Smckusick }
13441480Smckusick
nhpibrecv(unit,slave,sec,addr,origcnt)13545511Smckusick nhpibrecv(unit, slave, sec, addr, origcnt)
136*65637Sbostic int unit, slave, sec, origcnt;
13741480Smckusick register char *addr;
13841480Smckusick {
13941480Smckusick register struct hpib_softc *hs = &hpib_softc[unit];
14041480Smckusick register struct nhpibdevice *hd;
14145511Smckusick register int cnt = origcnt;
14241480Smckusick
14341480Smckusick hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
14441480Smckusick hd->hpib_acr = AUX_TCA;
14541480Smckusick hd->hpib_data = C_UNL;
14645511Smckusick if (nhpibwait(hd, MIS_BO))
14745511Smckusick goto recverror;
14841480Smckusick hd->hpib_data = C_LAG + hs->sc_ba;
14941480Smckusick hd->hpib_acr = AUX_SLON;
15045511Smckusick if (nhpibwait(hd, MIS_BO))
15145511Smckusick goto recverror;
15241480Smckusick hd->hpib_data = C_TAG + slave;
15345511Smckusick if (nhpibwait(hd, MIS_BO))
15445511Smckusick goto recverror;
15541480Smckusick if (sec != -1) {
15641480Smckusick hd->hpib_data = C_SCG + sec;
15745511Smckusick if (nhpibwait(hd, MIS_BO))
15845511Smckusick goto recverror;
15941480Smckusick }
16041480Smckusick hd->hpib_acr = AUX_RHDF;
16141480Smckusick hd->hpib_acr = AUX_GTS;
16241480Smckusick if (cnt) {
16341480Smckusick while (--cnt >= 0) {
16445511Smckusick if (nhpibwait(hd, MIS_BI))
16545511Smckusick goto recvbyteserror;
16641480Smckusick *addr++ = hd->hpib_data;
16741480Smckusick }
16841480Smckusick hd->hpib_acr = AUX_TCA;
16945511Smckusick hd->hpib_data = (slave == 31) ? C_UNA : C_UNT;
17045511Smckusick (void) nhpibwait(hd, MIS_BO);
17141480Smckusick }
17245511Smckusick return(origcnt);
17345511Smckusick recverror:
17445511Smckusick nhpibifc(hd);
17545511Smckusick recvbyteserror:
17645511Smckusick return(origcnt - cnt - 1);
17741480Smckusick }
17841480Smckusick
nhpibgo(unit,slave,sec,addr,count,rw)17941480Smckusick nhpibgo(unit, slave, sec, addr, count, rw)
18041480Smckusick register int unit, slave;
181*65637Sbostic int sec, count, rw;
18241480Smckusick char *addr;
18341480Smckusick {
18441480Smckusick register struct hpib_softc *hs = &hpib_softc[unit];
18541480Smckusick register struct nhpibdevice *hd;
18641480Smckusick
18741480Smckusick hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
18841480Smckusick hs->sc_flags |= HPIBF_IO;
18941480Smckusick if (rw == B_READ)
19041480Smckusick hs->sc_flags |= HPIBF_READ;
19141480Smckusick #ifdef DEBUG
19241480Smckusick else if (hs->sc_flags & HPIBF_READ) {
19341480Smckusick printf("nhpibgo: HPIBF_READ still set\n");
19441480Smckusick hs->sc_flags &= ~HPIBF_READ;
19541480Smckusick }
19641480Smckusick #endif
19741480Smckusick hs->sc_count = count;
19841480Smckusick hs->sc_addr = addr;
19941480Smckusick if (hs->sc_flags & HPIBF_READ) {
20041480Smckusick hs->sc_curcnt = count;
20141480Smckusick dmago(hs->sc_dq.dq_ctlr, addr, count, DMAGO_BYTE|DMAGO_READ);
20241480Smckusick nhpibrecv(unit, slave, sec, 0, 0);
20341480Smckusick hd->hpib_mim = MIS_END;
20445511Smckusick } else {
20545511Smckusick hd->hpib_mim = 0;
20645511Smckusick if (count < hpibdmathresh) {
20745511Smckusick hs->sc_curcnt = count;
20845511Smckusick nhpibsend(unit, slave, sec, addr, count);
20945511Smckusick nhpibdone(unit);
21045511Smckusick return;
21141480Smckusick }
21245511Smckusick hs->sc_curcnt = --count;
21345511Smckusick dmago(hs->sc_dq.dq_ctlr, addr, count, DMAGO_BYTE);
21445511Smckusick nhpibsend(unit, slave, sec, 0, 0);
21541480Smckusick }
21641480Smckusick hd->hpib_ie = IDS_IE | IDS_DMA(hs->sc_dq.dq_ctlr);
21741480Smckusick }
21841480Smckusick
nhpibdone(unit)21941480Smckusick nhpibdone(unit)
22041480Smckusick register int unit;
22141480Smckusick {
22241480Smckusick register struct hpib_softc *hs = &hpib_softc[unit];
22341480Smckusick register struct nhpibdevice *hd;
22441480Smckusick register int cnt;
22541480Smckusick
22641480Smckusick hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
22741480Smckusick cnt = hs->sc_curcnt;
22841480Smckusick hs->sc_addr += cnt;
22941480Smckusick hs->sc_count -= cnt;
23045511Smckusick hs->sc_flags |= HPIBF_DONE;
23145511Smckusick hd->hpib_ie = IDS_IE;
23245511Smckusick if ((hs->sc_flags & HPIBF_READ) == 0) {
23341480Smckusick if (hs->sc_count == 1) {
23445511Smckusick (void) nhpibwait(hd, MIS_BO);
23541480Smckusick hd->hpib_acr = AUX_EOI;
23645511Smckusick hd->hpib_data = *hs->sc_addr;
23745511Smckusick hd->hpib_mim = MIS_BO;
23841480Smckusick }
23945511Smckusick #ifdef DEBUG
24045511Smckusick else if (hs->sc_count)
24145511Smckusick panic("nhpibdone");
24245511Smckusick #endif
24341480Smckusick }
24441480Smckusick }
24541480Smckusick
nhpibintr(unit)24641480Smckusick nhpibintr(unit)
24741480Smckusick register int unit;
24841480Smckusick {
24941480Smckusick register struct hpib_softc *hs = &hpib_softc[unit];
25041480Smckusick register struct nhpibdevice *hd;
25145511Smckusick register struct devqueue *dq;
25241480Smckusick register int stat0;
25341480Smckusick int stat1;
25441480Smckusick
25541480Smckusick #ifdef lint
25641480Smckusick if (stat1 = unit) return(1);
25741480Smckusick #endif
25841480Smckusick hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
25941480Smckusick if ((hd->hpib_ids & IDS_IR) == 0)
26041480Smckusick return(0);
26141480Smckusick stat0 = hd->hpib_mis;
26241480Smckusick stat1 = hd->hpib_lis;
26345511Smckusick dq = hs->sc_sq.dq_forw;
26441480Smckusick if (hs->sc_flags & HPIBF_IO) {
26541480Smckusick hd->hpib_mim = 0;
26641480Smckusick if ((hs->sc_flags & HPIBF_DONE) == 0)
26741480Smckusick dmastop(hs->sc_dq.dq_ctlr);
26841480Smckusick hd->hpib_acr = AUX_TCA;
26941480Smckusick hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ);
27041480Smckusick dmafree(&hs->sc_dq);
27141480Smckusick (dq->dq_driver->d_intr)(dq->dq_unit);
27245511Smckusick } else if (hs->sc_flags & HPIBF_PPOLL) {
27341480Smckusick hd->hpib_mim = 0;
27441480Smckusick stat0 = nhpibppoll(unit);
27541480Smckusick if (stat0 & (0x80 >> dq->dq_slave)) {
27641480Smckusick hs->sc_flags &= ~HPIBF_PPOLL;
27741480Smckusick (dq->dq_driver->d_intr)(dq->dq_unit);
27841480Smckusick }
27945511Smckusick #ifdef DEBUG
28045511Smckusick else
28145511Smckusick printf("hpib%d: PPOLL intr bad status %x\n",
28245511Smckusick unit, stat0);
28345511Smckusick #endif
28441480Smckusick }
28541480Smckusick return(1);
28641480Smckusick }
28741480Smckusick
nhpibppoll(unit)28841480Smckusick nhpibppoll(unit)
28945511Smckusick int unit;
29041480Smckusick {
29141480Smckusick register struct nhpibdevice *hd;
29241480Smckusick register int ppoll;
29341480Smckusick
29445511Smckusick hd = (struct nhpibdevice *)hpib_softc[unit].sc_hc->hp_addr;
29541480Smckusick hd->hpib_acr = AUX_SPP;
29641480Smckusick DELAY(25);
29741480Smckusick ppoll = hd->hpib_cpt;
29841480Smckusick hd->hpib_acr = AUX_CPP;
29941480Smckusick return(ppoll);
30041480Smckusick }
30141480Smckusick
nhpibwait(hd,x)30245511Smckusick nhpibwait(hd, x)
30341480Smckusick register struct nhpibdevice *hd;
304*65637Sbostic int x;
30541480Smckusick {
30641480Smckusick register int timo = hpibtimeout;
30741480Smckusick
30845511Smckusick while ((hd->hpib_mis & x) == 0 && --timo)
30945511Smckusick DELAY(1);
31041480Smckusick if (timo == 0)
31141480Smckusick return(-1);
31241480Smckusick return(0);
31341480Smckusick }
31441480Smckusick
31554770Storek void
nhpibppwatch(arg)31654770Storek nhpibppwatch(arg)
31754770Storek void *arg;
31854770Storek {
31954770Storek register struct hpib_softc *hs;
32041480Smckusick register int unit;
32157347Shibler extern int cold;
32241480Smckusick
32354770Storek unit = (int)arg;
32454770Storek hs = &hpib_softc[unit];
32541480Smckusick if ((hs->sc_flags & HPIBF_PPOLL) == 0)
32641480Smckusick return;
32757347Shibler again:
32845511Smckusick if (nhpibppoll(unit) & (0x80 >> hs->sc_sq.dq_forw->dq_slave))
32941480Smckusick ((struct nhpibdevice *)hs->sc_hc->hp_addr)->hpib_mim = MIS_BO;
33057347Shibler else if (cold)
33157347Shibler /* timeouts not working yet */
33257347Shibler goto again;
33341480Smckusick else
33454770Storek timeout(nhpibppwatch, (void *)unit, 1);
33541480Smckusick }
33641480Smckusick #endif
337