Various diffs from Mike Hibler; necessary for mt driver.

This commit is contained in:
mycroft 1995-01-07 10:30:10 +00:00
parent 37e16c5747
commit 923bbe6e3b
5 changed files with 256 additions and 89 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: fhpib.c,v 1.5 1994/10/26 07:23:43 cgd Exp $ */
/* $NetBSD: fhpib.c,v 1.6 1995/01/07 10:30:10 mycroft Exp $ */
/*
* Copyright (c) 1982, 1990, 1993
@ -43,6 +43,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/buf.h>
#include <hp300/dev/device.h>
@ -152,7 +153,10 @@ fhpibsend(unit, slave, sec, addr, origcnt)
hd->hpib_data = C_UNL;
hd->hpib_data = C_TAG + hs->sc_ba;
hd->hpib_data = C_LAG + slave;
if (sec != -1)
if (sec < 0) {
if (sec == -2) /* selected device clear KLUDGE */
hd->hpib_data = C_SDC;
} else
hd->hpib_data = C_SCG + sec;
if (fhpibwait(hd, IM_IDLE) < 0)
goto senderr;
@ -179,6 +183,7 @@ fhpibsend(unit, slave, sec, addr, origcnt)
}
hd->hpib_imask = 0;
return (origcnt);
senderr:
hd->hpib_imask = 0;
fhpibifc(hd);
@ -189,7 +194,7 @@ senderr:
printf("sent %d of %d bytes\n", origcnt-cnt-1, origcnt);
}
#endif
return(origcnt - cnt - 1);
return (origcnt - cnt - 1);
}
fhpibrecv(unit, slave, sec, addr, origcnt)
@ -202,20 +207,26 @@ fhpibrecv(unit, slave, sec, addr, origcnt)
register int timo;
hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
hd->hpib_stat = 0;
hd->hpib_imask = IM_IDLE | IM_ROOM | IM_BYTE;
if (fhpibwait(hd, IM_IDLE) < 0)
goto recverror;
hd->hpib_stat = ST_ATN;
hd->hpib_data = C_UNL;
hd->hpib_data = C_LAG + hs->sc_ba;
hd->hpib_data = C_TAG + slave;
if (sec != -1)
hd->hpib_data = C_SCG + sec;
if (fhpibwait(hd, IM_IDLE) < 0)
goto recverror;
hd->hpib_stat = ST_READ0;
hd->hpib_data = 0;
/*
* Slave < 0 implies continuation of a previous receive
* that probably timed out.
*/
if (slave >= 0) {
hd->hpib_stat = 0;
hd->hpib_imask = IM_IDLE | IM_ROOM | IM_BYTE;
if (fhpibwait(hd, IM_IDLE) < 0)
goto recverror;
hd->hpib_stat = ST_ATN;
hd->hpib_data = C_UNL;
hd->hpib_data = C_LAG + hs->sc_ba;
hd->hpib_data = C_TAG + slave;
if (sec != -1)
hd->hpib_data = C_SCG + sec;
if (fhpibwait(hd, IM_IDLE) < 0)
goto recverror;
hd->hpib_stat = ST_READ0;
hd->hpib_data = 0;
}
if (cnt) {
while (--cnt >= 0) {
timo = hpibtimeout;
@ -245,10 +256,10 @@ recvbyteserror:
printf("got %d of %d bytes\n", origcnt-cnt-1, origcnt);
}
#endif
return(origcnt - cnt - 1);
return (origcnt - cnt - 1);
}
fhpibgo(unit, slave, sec, addr, count, rw)
fhpibgo(unit, slave, sec, addr, count, rw, timo)
register int unit;
int slave, sec, count, rw;
char *addr;
@ -258,11 +269,10 @@ fhpibgo(unit, slave, sec, addr, count, rw)
register int i;
int flags = 0;
#ifdef lint
i = unit; if (i) return;
#endif
hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
hs->sc_flags |= HPIBF_IO;
if (timo)
hs->sc_flags |= HPIBF_TIMO;
if (rw == B_READ)
hs->sc_flags |= HPIBF_READ;
#ifdef DEBUG
@ -335,6 +345,42 @@ fhpibgo(unit, slave, sec, addr, count, rw)
((flags & DMAGO_WORD) ? IDS_WDMA : 0);
}
/*
* A DMA read can finish but the device can still be waiting (MAG-tape
* with more data than we're waiting for). This timeout routine
* takes care of that. Somehow, the thing gets hosed. For now, since
* this should be a very rare occurence, we RESET it.
*/
void
fhpibdmadone(arg)
void *arg;
{
register int unit;
register struct hpib_softc *hs;
int s = splbio();
unit = (int)arg;
hs = &hpib_softc[unit];
if (hs->sc_flags & HPIBF_IO) {
register struct fhpibdevice *hd;
register struct devqueue *dq;
hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
hd->hpib_imask = 0;
hd->hpib_cid = 0xFF;
DELAY(100);
hd->hpib_cmd = CT_8BIT;
hd->hpib_ar = AR_ARONC;
fhpibifc(hd);
hd->hpib_ie = IDS_IE;
hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
dmafree(&hs->sc_dq);
dq = hs->sc_sq.dq_forw;
(dq->dq_driver->d_intr)(dq->dq_unit);
}
(void) splx(s);
}
fhpibdone(unit)
int unit;
{
@ -352,9 +398,11 @@ fhpibdone(unit)
printf("fhpibdone: addr %x cnt %d\n",
hs->sc_addr, hs->sc_count);
#endif
if (hs->sc_flags & HPIBF_READ)
if (hs->sc_flags & HPIBF_READ) {
hd->hpib_imask = IM_IDLE | IM_BYTE;
else {
if (hs->sc_flags & HPIBF_TIMO)
timeout(fhpibdmadone, (void *)unit, hz >> 2);
} else {
cnt = hs->sc_count;
if (cnt) {
addr = hs->sc_addr;
@ -407,13 +455,15 @@ fhpibintr(unit)
#endif
dq = hs->sc_sq.dq_forw;
if (hs->sc_flags & HPIBF_IO) {
if (hs->sc_flags & HPIBF_TIMO)
untimeout(fhpibdmadone, (void *)unit);
stat0 = hd->hpib_cmd;
hd->hpib_cmd = fhpibcmd[unit] & ~CT_8BIT;
hd->hpib_stat = 0;
hd->hpib_cmd = CT_REN | CT_8BIT;
stat0 = hd->hpib_intr;
hd->hpib_imask = 0;
hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ);
hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
dmafree(&hs->sc_dq);
(dq->dq_driver->d_intr)(dq->dq_unit);
} else if (hs->sc_flags & HPIBF_PPOLL) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: hpib.c,v 1.4 1994/10/26 07:24:17 cgd Exp $ */
/* $NetBSD: hpib.c,v 1.5 1995/01/07 10:30:12 mycroft Exp $ */
/*
* Copyright (c) 1982, 1990, 1993
@ -164,6 +164,12 @@ hpibpptest(unit, slave)
return((*ppoll)(unit) & (0x80 >> slave));
}
hpibppclear(unit)
int unit;
{
hpib_softc[unit].sc_flags &= ~HPIBF_PPOLL;
}
hpibawait(unit)
int unit;
{
@ -216,14 +222,14 @@ hpibstart(unit)
(dq->dq_driver->d_go)(dq->dq_unit);
}
hpibgo(unit, slave, sec, addr, count, rw)
hpibgo(unit, slave, sec, addr, count, rw, timo)
register int unit;
int slave, sec, addr, count, rw;
{
if (hpib_softc[unit].sc_type == HPIBC)
fhpibgo(unit, slave, sec, addr, count, rw);
fhpibgo(unit, slave, sec, addr, count, rw, timo);
else
nhpibgo(unit, slave, sec, addr, count, rw);
nhpibgo(unit, slave, sec, addr, count, rw, timo);
}
hpibdone(unit)

View File

@ -1,4 +1,4 @@
/* $NetBSD: hpibvar.h,v 1.4 1994/10/26 07:24:19 cgd Exp $ */
/* $NetBSD: hpibvar.h,v 1.5 1995/01/07 10:30:13 mycroft Exp $ */
/*
* Copyright (c) 1982, 1990, 1993
@ -52,13 +52,19 @@
#define IDS_IE 0x80
#define IDS_DMA(x) (1 << (x))
#define C_DCL 0x14
#define C_LAG 0x20
#define C_UNL 0x3f
#define C_TAG 0x40
#define C_UNA 0x5e
#define C_UNT 0x5f
#define C_SCG 0x60
#define C_SDC 0x04 /* Selected device clear */
#define C_SDC_P 0x04 /* with odd parity */
#define C_DCL 0x14 /* Universal device clear */
#define C_DCL_P 0x94 /* with odd parity */
#define C_LAG 0x20 /* Listener address group commands */
#define C_UNL 0x3f /* Universal unlisten */
#define C_UNL_P 0xbf /* with odd parity */
#define C_TAG 0x40 /* Talker address group commands */
#define C_UNA 0x5e /* Unaddress (master talk address?) */
#define C_UNA_P 0x5e /* with odd parity */
#define C_UNT 0x5f /* Universal untalk */
#define C_UNT_P 0xdf /* with odd parity */
#define C_SCG 0x60 /* Secondary group commands */
struct hpib_softc {
struct hp_ctlr *sc_hc;
@ -77,6 +83,7 @@ struct hpib_softc {
#define HPIBF_DONE 0x2
#define HPIBF_PPOLL 0x4
#define HPIBF_READ 0x8
#define HPIBF_TIMO 0x10
#define HPIBF_DMA16 0x8000
#ifdef KERNEL

View File

@ -1,4 +1,4 @@
/* $NetBSD: nhpib.c,v 1.5 1994/10/26 07:24:44 cgd Exp $ */
/* $NetBSD: nhpib.c,v 1.6 1995/01/07 10:30:14 mycroft Exp $ */
/*
* Copyright (c) 1982, 1990, 1993
@ -43,6 +43,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/buf.h>
#include <hp300/dev/device.h>
@ -50,6 +51,29 @@
#include <hp300/dev/hpibvar.h>
#include <hp300/dev/dmavar.h>
/*
* ODD parity table for listen and talk addresses and secondary commands.
* The TI9914A doesn't produce the parity bit.
*/
static u_char listnr_par[] = {
0040,0241,0242,0043,0244,0045,0046,0247,
0250,0051,0052,0253,0054,0255,0256,0057,
0260,0061,0062,0263,0064,0265,0266,0067,
0070,0271,0272,0073,0274,0075,0076,0277,
};
static u_char talker_par[] = {
0100,0301,0302,0103,0304,0105,0106,0307,
0310,0111,0112,0313,0114,0315,0316,0117,
0320,0121,0122,0323,0124,0325,0326,0127,
0130,0331,0332,0133,0334,0135,0136,0337,
};
static u_char sec_par[] = {
0340,0141,0142,0343,0144,0345,0346,0147,
0150,0351,0352,0153,0354,0155,0156,0357,
0160,0361,0362,0163,0364,0165,0166,0367,
0370,0171,0172,0373,0174,0375,0376,0177
};
nhpibtype(hc)
register struct hp_ctlr *hc;
{
@ -93,7 +117,7 @@ nhpibreset(unit)
hd->hpib_acr = AUX_CSWRST;
nhpibifc(hd);
hd->hpib_ie = IDS_IE;
hd->hpib_data = C_DCL;
hd->hpib_data = C_DCL_P;
DELAY(100000);
}
@ -118,18 +142,21 @@ nhpibsend(unit, slave, sec, addr, origcnt)
hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
hd->hpib_acr = AUX_TCA;
hd->hpib_data = C_UNL;
hd->hpib_data = C_UNL_P;
if (nhpibwait(hd, MIS_BO))
goto senderror;
hd->hpib_data = C_TAG + hs->sc_ba;
hd->hpib_data = talker_par[hs->sc_ba];
hd->hpib_acr = AUX_STON;
if (nhpibwait(hd, MIS_BO))
goto senderror;
hd->hpib_data = C_LAG + slave;
hd->hpib_data = listnr_par[slave];
if (nhpibwait(hd, MIS_BO))
goto senderror;
if (sec != -1) {
hd->hpib_data = C_SCG + sec;
if (sec >= 0 || sec == -2) {
if (sec == -2) /* selected device clear KLUDGE */
hd->hpib_data = C_SDC_P;
else
hd->hpib_data = sec_par[sec];
if (nhpibwait(hd, MIS_BO))
goto senderror;
}
@ -150,11 +177,12 @@ nhpibsend(unit, slave, sec, addr, origcnt)
* May be causing 345 disks to hang due to interference
* with PPOLL mechanism.
*/
hd->hpib_data = C_UNL;
hd->hpib_data = C_UNL_P;
(void) nhpibwait(hd, MIS_BO);
#endif
}
return(origcnt);
senderror:
nhpibifc(hd);
return(origcnt - cnt - 1);
@ -169,24 +197,30 @@ nhpibrecv(unit, slave, sec, addr, origcnt)
register int cnt = origcnt;
hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
hd->hpib_acr = AUX_TCA;
hd->hpib_data = C_UNL;
if (nhpibwait(hd, MIS_BO))
goto recverror;
hd->hpib_data = C_LAG + hs->sc_ba;
hd->hpib_acr = AUX_SLON;
if (nhpibwait(hd, MIS_BO))
goto recverror;
hd->hpib_data = C_TAG + slave;
if (nhpibwait(hd, MIS_BO))
goto recverror;
if (sec != -1) {
hd->hpib_data = C_SCG + sec;
/*
* Slave < 0 implies continuation of a previous receive
* that probably timed out.
*/
if (slave >= 0) {
hd->hpib_acr = AUX_TCA;
hd->hpib_data = C_UNL_P;
if (nhpibwait(hd, MIS_BO))
goto recverror;
hd->hpib_data = listnr_par[hs->sc_ba];
hd->hpib_acr = AUX_SLON;
if (nhpibwait(hd, MIS_BO))
goto recverror;
hd->hpib_data = talker_par[slave];
if (nhpibwait(hd, MIS_BO))
goto recverror;
if (sec >= 0) {
hd->hpib_data = sec_par[sec];
if (nhpibwait(hd, MIS_BO))
goto recverror;
}
hd->hpib_acr = AUX_RHDF;
hd->hpib_acr = AUX_GTS;
}
hd->hpib_acr = AUX_RHDF;
hd->hpib_acr = AUX_GTS;
if (cnt) {
while (--cnt >= 0) {
if (nhpibwait(hd, MIS_BI))
@ -194,17 +228,18 @@ nhpibrecv(unit, slave, sec, addr, origcnt)
*addr++ = hd->hpib_data;
}
hd->hpib_acr = AUX_TCA;
hd->hpib_data = (slave == 31) ? C_UNA : C_UNT;
hd->hpib_data = (slave == 31) ? C_UNA_P : C_UNT_P;
(void) nhpibwait(hd, MIS_BO);
}
return(origcnt);
recverror:
nhpibifc(hd);
recvbyteserror:
return(origcnt - cnt - 1);
}
nhpibgo(unit, slave, sec, addr, count, rw)
nhpibgo(unit, slave, sec, addr, count, rw, timo)
register int unit, slave;
int sec, count, rw;
char *addr;
@ -214,6 +249,8 @@ nhpibgo(unit, slave, sec, addr, count, rw)
hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
hs->sc_flags |= HPIBF_IO;
if (timo)
hs->sc_flags |= HPIBF_TIMO;
if (rw == B_READ)
hs->sc_flags |= HPIBF_READ;
#ifdef DEBUG
@ -244,6 +281,38 @@ nhpibgo(unit, slave, sec, addr, count, rw)
hd->hpib_ie = IDS_IE | IDS_DMA(hs->sc_dq.dq_ctlr);
}
/*
* This timeout can only happen if a DMA read finishes DMAing with the read
* still pending (more data in read transaction than the driver was prepared
* to accept). At the moment, variable-record tape drives are the only things
* capabale of doing this. We repeat the necessary code from nhpibintr() -
* easier and quicker than calling nhpibintr() for this special case.
*/
void
nhpibreadtimo(arg)
void *arg;
{
int unit;
register struct hpib_softc *hs;
int s = splbio();
unit = (int)arg;
hs = &hpib_softc[unit];
if (hs->sc_flags & HPIBF_IO) {
register struct nhpibdevice *hd;
register struct devqueue *dq;
hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
hd->hpib_mim = 0;
hd->hpib_acr = AUX_TCA;
hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
dmafree(&hs->sc_dq);
dq = hs->sc_sq.dq_forw;
(dq->dq_driver->d_intr)(dq->dq_unit);
}
(void) splx(s);
}
nhpibdone(unit)
register int unit;
{
@ -257,7 +326,11 @@ nhpibdone(unit)
hs->sc_count -= cnt;
hs->sc_flags |= HPIBF_DONE;
hd->hpib_ie = IDS_IE;
if ((hs->sc_flags & HPIBF_READ) == 0) {
if (hs->sc_flags & HPIBF_READ) {
if ((hs->sc_flags & HPIBF_TIMO) &&
(hd->hpib_ids & IDS_IR) == 0)
timeout(nhpibreadtimo, (void *)unit, hz >> 2);
} else {
if (hs->sc_count == 1) {
(void) nhpibwait(hd, MIS_BO);
hd->hpib_acr = AUX_EOI;
@ -291,10 +364,13 @@ nhpibintr(unit)
dq = hs->sc_sq.dq_forw;
if (hs->sc_flags & HPIBF_IO) {
hd->hpib_mim = 0;
if ((hs->sc_flags & HPIBF_DONE) == 0)
if ((hs->sc_flags & HPIBF_DONE) == 0) {
hs->sc_flags &= ~HPIBF_TIMO;
dmastop(hs->sc_dq.dq_ctlr);
} else if (hs->sc_flags & HPIBF_TIMO)
untimeout(nhpibreadtimo, (void *)unit);
hd->hpib_acr = AUX_TCA;
hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ);
hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
dmafree(&hs->sc_dq);
(dq->dq_driver->d_intr)(dq->dq_unit);
} else if (hs->sc_flags & HPIBF_PPOLL) {
@ -327,6 +403,10 @@ nhpibppoll(unit)
return(ppoll);
}
#ifdef DEBUG
int nhpibreporttimo = 0;
#endif
nhpibwait(hd, x)
register struct nhpibdevice *hd;
int x;
@ -335,8 +415,13 @@ nhpibwait(hd, x)
while ((hd->hpib_mis & x) == 0 && --timo)
DELAY(1);
if (timo == 0)
if (timo == 0) {
#ifdef DEBUG
if (nhpibreporttimo)
printf("hpib0: %s timo\n", x==MIS_BO?"OUT":"IN");
#endif
return(-1);
}
return(0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: nhpibreg.h,v 1.4 1994/10/26 07:24:45 cgd Exp $ */
/* $NetBSD: nhpibreg.h,v 1.5 1995/01/07 10:30:15 mycroft Exp $ */
/*
* Copyright (c) 1982, 1990, 1993
@ -67,8 +67,17 @@ struct nhpibdevice {
vu_char hpib_data;
};
/*
* Bits in hpib_lis (and hpib_lim).
*/
#define LIS_IFC 0x01
#define LIS_SRQ 0x02
#define LIS_MA 0x04
#define LIS_DCAS 0x08
#define LIS_APT 0x10
#define LIS_UCG 0x20
#define LIS_ERR 0x40
#define LIS_GET 0x80
#define MIS_END 0x08
#define MIS_BO 0x10
@ -77,26 +86,36 @@ struct nhpibdevice {
#define IS_TADS 0x02
#define IS_LADS 0x04
#define AUX_CSWRST 0
#define AUX_RHDF 2
#define AUX_CHDFA 3
#define AUX_CHDFE 4
#define AUX_EOI 8
#define AUX_GTS 11
#define AUX_TCA 12
#define AUX_TCS 13
#define AUX_CPP 14
#define AUX_CSIC 15
#define AUX_CSRE 16
#define AUX_CDAI 19
#define AUX_CSHDW 22
#define AUX_SSWRST 128
#define AUX_SHDFE 132
#define AUX_SLON 137
#define AUX_STON 138
#define AUX_SPP 142
#define AUX_SSIC 143
#define AUX_SSRE 144
#define AUX_SSTD1 149
#define AUX_SVSTD1 151
/*
* ti9914 "Auxiliary Commands" - Some are Set/Clear, others pulse.
*/
#define AUX_CSWRST 0x00 /* End software reset */
#define AUX_RHDF 0x02 /* release RFD (ready for data) holdoff */
#define AUX_CHDFA 0x03 /* Clear holdoff on all data */
#define AUX_CHDFE 0x04 /* Clear holdoff on EOI data only */
#define AUX_EOI 0x08 /* Pulse EOI (with data) */
#define AUX_CLON 0x09 /* Clear listen only */
#define AUX_CTON 0x0a /* Clear talk only */
#define AUX_GTS 0x0b /* Go to standby (clears ATN line) */
#define AUX_TCA 0x0c /* Take control (async) */
#define AUX_TCS 0x0d /* Take control (sync) */
#define AUX_CPP 0x0e /* Clear parallel poll */
#define AUX_CSIC 0x0f /* Clear IFC (interface clear) line */
#define AUX_CSRE 0x10 /* Clear REN (remote enable) line */
#define AUX_CDAI 0x13 /* Clear interrupt disable */
#define AUX_CSTD1 0x15 /* Clear 1200ns T1 delay */
#define AUX_CSHDW 0x16 /* Clear shadow handshake */
#define AUX_CVSTD1 0x17 /* Clear 600ns T1 delay */
#define AUX_SSWRST 0x80 /* Start software reset */
#define AUX_SHDFA 0x83 /* Set holdoff on all data */
#define AUX_SHDFE 0x84 /* Set holdoff on EOI data only */
#define AUX_SLON 0x89 /* Set listen only */
#define AUX_STON 0x8a /* Set talk only */
#define AUX_SPP 0x8e /* Set parallel poll */
#define AUX_SSIC 0x8f /* Set IFC line */
#define AUX_SSRE 0x90 /* Set REN line */
#define AUX_SDAI 0x93 /* Disable all interrupts */
#define AUX_SSTD1 0x95 /* Set T1 delay to 1200ns */
#define AUX_SSHDW 0x96 /* Set shadow handshake */
#define AUX_SVSTD1 0x97 /* Set T1 delay to 600ns */