use if_timer instead of private timeout
SCCS-vsn: sys/vax/if/if_dmc.c 7.2
SCCS-vsn: sys/vax/if/if_dmv.c 7.3
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
- * @(#)if_dmc.c 7.1 (Berkeley) %G%
+ * @(#)if_dmc.c 7.2 (Berkeley) %G%
#include "../h/time.h"
#include "../h/kernel.h"
#include "../h/time.h"
#include "../h/kernel.h"
-int dmctimer; /* timer started? */
-int dmc_timeout = 8; /* timeout value */
-int dmcwatch();
+/*
+ * output timeout value, sec.; should depend on line speed.
+ */
+int dmc_timeout = 20;
/*
* Driver information for auto-configuration stuff.
*/
int dmcprobe(), dmcattach(), dmcinit(), dmcioctl();
/*
* Driver information for auto-configuration stuff.
*/
int dmcprobe(), dmcattach(), dmcinit(), dmcioctl();
-int dmcoutput(), dmcreset();
+int dmcoutput(), dmcreset(), dmctimeout();
struct uba_device *dmcinfo[NDMC];
u_short dmcstd[] = { 0 };
struct uba_driver dmcdriver =
struct uba_device *dmcinfo[NDMC];
u_short dmcstd[] = { 0 };
struct uba_driver dmcdriver =
*/
struct dmc_softc {
struct ifnet sc_if; /* network-visible interface */
*/
struct dmc_softc {
struct ifnet sc_if; /* network-visible interface */
- struct dmcbufs sc_rbufs[NRCV]; /* receive buffer info */
- struct dmcbufs sc_xbufs[NXMT]; /* transmit buffer info */
- struct ifubinfo sc_ifuba; /* UNIBUS resources */
- struct ifrw sc_ifr[NRCV]; /* UNIBUS receive buffer maps */
- struct ifxmt sc_ifw[NXMT]; /* UNIBUS receive buffer maps */
short sc_oused; /* output buffers currently in use */
short sc_iused; /* input buffers given to DMC */
short sc_flag; /* flags */
short sc_oused; /* output buffers currently in use */
short sc_iused; /* input buffers given to DMC */
short sc_flag; /* flags */
- int sc_nticks; /* seconds since last interrupt */
int sc_ubinfo; /* UBA mapping info for base table */
int sc_errors[4]; /* non-fatal error counters */
#define sc_datck sc_errors[0]
#define sc_timeo sc_errors[1]
#define sc_nobuf sc_errors[2]
#define sc_disc sc_errors[3]
int sc_ubinfo; /* UBA mapping info for base table */
int sc_errors[4]; /* non-fatal error counters */
#define sc_datck sc_errors[0]
#define sc_timeo sc_errors[1]
#define sc_nobuf sc_errors[2]
#define sc_disc sc_errors[3]
+ struct dmcbufs sc_rbufs[NRCV]; /* receive buffer info */
+ struct dmcbufs sc_xbufs[NXMT]; /* transmit buffer info */
+ struct ifubinfo sc_ifuba; /* UNIBUS resources */
+ struct ifrw sc_ifr[NRCV]; /* UNIBUS receive buffer maps */
+ struct ifxmt sc_ifw[NXMT]; /* UNIBUS receive buffer maps */
/* command queue stuff */
struct dmc_command sc_cmdbuf[NCMDS];
struct dmc_command *sc_qhead; /* head of command queue */
/* command queue stuff */
struct dmc_command sc_cmdbuf[NCMDS];
struct dmc_command *sc_qhead; /* head of command queue */
} dmc_softc[NDMC];
/* flags */
} dmc_softc[NDMC];
/* flags */
-#define DMC_ALLOC 0x01 /* unibus resources allocated */
+#define DMC_RUNNING 0x01 /* device initialized */
#define DMC_BMAPPED 0x02 /* base table mapped */
#define DMC_RESTART 0x04 /* software restart in progress */
#define DMC_BMAPPED 0x02 /* base table mapped */
#define DMC_RESTART 0x04 /* software restart in progress */
-#define DMC_ACTIVE 0x08 /* device active */
-#define DMC_RUNNING 0x20 /* device initialized */
+#define DMC_ONLINE 0x08 /* device running (had a RDYO) */
struct dmc_base {
short d_base[128]; /* DMC base table */
struct dmc_base {
short d_base[128]; /* DMC base table */
sc->sc_if.if_output = dmcoutput;
sc->sc_if.if_ioctl = dmcioctl;
sc->sc_if.if_reset = dmcreset;
sc->sc_if.if_output = dmcoutput;
sc->sc_if.if_ioctl = dmcioctl;
sc->sc_if.if_reset = dmcreset;
+ sc->sc_if.if_watchdog = dmctimeout;
sc->sc_if.if_flags = IFF_POINTOPOINT;
sc->sc_ifuba.iff_flags = UBA_CANTWAIT;
sc->sc_if.if_flags = IFF_POINTOPOINT;
sc->sc_ifuba.iff_flags = UBA_CANTWAIT;
- if (dmctimer == 0) {
- dmctimer = 1;
- timeout(dmcwatch, (caddr_t) 0, hz);
- }
}
ifp->if_flags |= IFF_RUNNING;
}
}
ifp->if_flags |= IFF_RUNNING;
}
+ sc->sc_flag &= ~DMC_ONLINE;
sc->sc_flag |= DMC_RUNNING;
sc->sc_flag |= DMC_RUNNING;
+ /*
+ * Limit packets enqueued until we see if we're on the air.
+ */
+ ifp->if_snd.ifq_maxlen = 3;
/* initialize buffer pool */
/* receives */
/* initialize buffer pool */
/* receives */
dmcload(sc, DMC_CNTLI, 0, DMC_HDPLX | DMC_SEC);
/* enable operation done interrupts */
dmcload(sc, DMC_CNTLI, 0, DMC_HDPLX | DMC_SEC);
/* enable operation done interrupts */
- sc->sc_flag &= ~DMC_ACTIVE;
while ((addr->bsel2 & DMC_IEO) == 0)
addr->bsel2 |= DMC_IEO;
s = spl5();
while ((addr->bsel2 & DMC_IEO) == 0)
addr->bsel2 |= DMC_IEO;
s = spl5();
*
* Must be called at spl 5
*/
*
* Must be called at spl 5
*/
-dmcstart(dev)
- dev_t dev;
+dmcstart(unit)
+ int unit;
register struct dmc_softc *sc = &dmc_softc[unit];
struct mbuf *m;
register struct dmcbufs *rp;
register struct dmc_softc *sc = &dmc_softc[unit];
struct mbuf *m;
register struct dmcbufs *rp;
*/
rp->cc = if_ubaput(&sc->sc_ifuba, &sc->sc_ifw[n], m);
rp->cc &= DMC_CCOUNT;
*/
rp->cc = if_ubaput(&sc->sc_ifuba, &sc->sc_ifw[n], m);
rp->cc &= DMC_CCOUNT;
+ if (++sc->sc_oused == 1)
+ sc->sc_if.if_timer = dmc_timeout;
dmcload(sc, DMC_WRITE, rp->ubinfo,
rp->cc | ((rp->ubinfo>>2)&DMC_XMEM));
}
dmcload(sc, DMC_WRITE, rp->ubinfo,
rp->cc | ((rp->ubinfo>>2)&DMC_XMEM));
}
ifxp->ifw_xtofree = 0;
}
rp->flags &= ~DBUF_DMCS;
ifxp->ifw_xtofree = 0;
}
rp->flags &= ~DBUF_DMCS;
- sc->sc_oused--;
- sc->sc_nticks = 0;
- sc->sc_flag |= DMC_ACTIVE;
+ if (--sc->sc_oused == 0)
+ sc->sc_if.if_timer = 0;
+ else
+ sc->sc_if.if_timer = dmc_timeout;
+ if ((sc->sc_flag & DMC_ONLINE) == 0) {
+ extern int ifqmaxlen;
+
+ /*
+ * We're on the air.
+ * Open the queue to the usual value.
+ */
+ sc->sc_flag |= DMC_ONLINE;
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+ }
break;
case DMC_CNTLO:
arg &= DMC_CNTMASK;
if (arg & DMC_FATAL) {
break;
case DMC_CNTLO:
arg &= DMC_CNTMASK;
if (arg & DMC_FATAL) {
- log(LOG_ERR, "dmc%d: fatal error, flags=%b\n",
- unit, arg, CNTLO_BITS);
+ if (arg != DMC_START)
+ log(LOG_ERR,
+ "dmc%d: fatal error, flags=%b\n",
+ unit, arg, CNTLO_BITS);
dmcrestart(unit);
break;
}
dmcrestart(unit);
break;
}
register struct dmc_header *dh;
register int off;
register struct dmc_header *dh;
register int off;
+ if ((ifp->if_flags & IFF_UP) == 0) {
+ error = ENETDOWN;
+ goto bad;
+ }
+
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
case SIOCSIFFLAGS:
if ((ifp->if_flags & IFF_UP) == 0 &&
case SIOCSIFFLAGS:
if ((ifp->if_flags & IFF_UP) == 0 &&
- sc->sc_flag & DMC_RUNNING) {
- ((struct dmcdevice *)
- (dmcinfo[ifp->if_unit]->ui_addr))->bsel1 = DMC_MCLR;
- sc->sc_flag &= ~DMC_RUNNING;
- } else if (ifp->if_flags & IFF_UP &&
+ sc->sc_flag & DMC_RUNNING)
+ dmcdown(ifp->if_unit);
+ else if (ifp->if_flags & IFF_UP &&
(sc->sc_flag & DMC_RUNNING) == 0)
dmcrestart(ifp->if_unit);
break;
(sc->sc_flag & DMC_RUNNING) == 0)
dmcrestart(ifp->if_unit);
break;
int unit;
{
register struct dmc_softc *sc = &dmc_softc[unit];
int unit;
{
register struct dmc_softc *sc = &dmc_softc[unit];
- register struct uba_device *ui = dmcinfo[unit];
register struct dmcdevice *addr;
register struct dmcdevice *addr;
- register struct ifxmt *ifxp;
- addr = (struct dmcdevice *)ui->ui_addr;
#ifdef DEBUG
/* dump base table */
printf("dmc%d base table:\n", unit);
for (i = 0; i < sizeof (struct dmc_base); i++)
printf("%o\n" ,dmc_base[unit].d_base[i]);
#endif
#ifdef DEBUG
/* dump base table */
printf("dmc%d base table:\n", unit);
for (i = 0; i < sizeof (struct dmc_base); i++)
printf("%o\n" ,dmc_base[unit].d_base[i]);
#endif
/*
* Let the DMR finish the MCLR. At 1 Mbit, it should do so
* in about a max of 6.4 milliseconds with diagnostics enabled.
*/
/*
* Let the DMR finish the MCLR. At 1 Mbit, it should do so
* in about a max of 6.4 milliseconds with diagnostics enabled.
*/
- addr->bsel1 = DMC_MCLR;
+ addr = (struct dmcdevice *)(dmcinfo[unit]->ui_addr);
for (i = 100000; i && (addr->bsel1 & DMC_RUN) == 0; i--)
;
/* Did the timer expire or did the DMR finish? */
for (i = 100000; i && (addr->bsel1 & DMC_RUN) == 0; i--)
;
/* Did the timer expire or did the DMR finish? */
+ /* restart DMC */
+ dmcinit(unit);
+ sc->sc_flag &= ~DMC_RESTART;
+ s = spl5();
+ dmcstart(unit);
+ splx(s);
+ sc->sc_if.if_collisions++; /* why not? */
+}
+
+/*
+ * Reset a device and mark down.
+ * Flush output queue and drop queue limit.
+ */
+dmcdown(unit)
+ int unit;
+{
+ register struct dmc_softc *sc = &dmc_softc[unit];
+ register struct ifxmt *ifxp;
+
+ ((struct dmcdevice *)(dmcinfo[unit]->ui_addr))->bsel1 = DMC_MCLR;
+ sc->sc_flag &= ~(DMC_RUNNING | DMC_ONLINE);
+
for (ifxp = sc->sc_ifw; ifxp < &sc->sc_ifw[NXMT]; ifxp++) {
if (ifxp->ifw_xtofree) {
(void) m_freem(ifxp->ifw_xtofree);
ifxp->ifw_xtofree = 0;
}
}
for (ifxp = sc->sc_ifw; ifxp < &sc->sc_ifw[NXMT]; ifxp++) {
if (ifxp->ifw_xtofree) {
(void) m_freem(ifxp->ifw_xtofree);
ifxp->ifw_xtofree = 0;
}
}
-
- /* restart DMC */
- dmcinit(unit);
- sc->sc_flag &= ~DMC_RESTART;
- sc->sc_if.if_collisions++; /* why not? */
+ if_qflush(&sc->sc_if.if_snd);
- * Check to see that transmitted packets don't
- * lose interrupts. The device has to be active.
+ * Watchdog timeout to see that transmitted packets don't
+ * lose interrupts. The device has to be online (the first
+ * transmission may block until the other side comes up).
+dmctimeout(unit)
+ int unit;
- register struct uba_device *ui;
register struct dmc_softc *sc;
struct dmcdevice *addr;
register struct dmc_softc *sc;
struct dmcdevice *addr;
- for (i = 0; i < NDMC; i++) {
- sc = &dmc_softc[i];
- if ((sc->sc_flag & DMC_ACTIVE) == 0)
- continue;
- if ((ui = dmcinfo[i]) == 0 || ui->ui_alive == 0)
- continue;
- if (sc->sc_oused) {
- sc->sc_nticks++;
- if (sc->sc_nticks > dmc_timeout) {
- sc->sc_nticks = 0;
- addr = (struct dmcdevice *)ui->ui_addr;
- log(LOG_ERR, "dmc%d hung: bsel0=%b bsel2=%b\n",
- i, addr->bsel0 & 0xff, DMC0BITS,
- addr->bsel2 & 0xff, DMC2BITS);
- dmcrestart(i);
- }
- }
+ sc = &dmc_softc[unit];
+ if (sc->sc_flag & DMC_ONLINE) {
+ addr = (struct dmcdevice *)(dmcinfo[unit]->ui_addr);
+ log(LOG_ERR, "dmc%d: output timeout, bsel0=%b bsel2=%b\n",
+ unit, addr->bsel0 & 0xff, DMC0BITS,
+ addr->bsel2 & 0xff, DMC2BITS);
+ dmcrestart(unit);
- timeout(dmcwatch, (caddr_t) 0, hz);
- * @(#)if_dmv.c 7.2 (Berkeley) %G%
+ * @(#)if_dmv.c 7.3 (Berkeley) %G%
* DMV-11 Driver
*
* Qbus Sync DDCMP interface - DMV operated in full duplex, point to point mode
* DMV-11 Driver
*
* Qbus Sync DDCMP interface - DMV operated in full duplex, point to point mode
#include "dmv.h"
#if NDMV > 0
#include "dmv.h"
#if NDMV > 0
-
-#include "../machine/pte.h"
-
#include "param.h"
#include "systm.h"
#include "mbuf.h"
#include "param.h"
#include "systm.h"
#include "mbuf.h"
#include "syslog.h"
#include "vmmac.h"
#include "errno.h"
#include "syslog.h"
#include "vmmac.h"
#include "errno.h"
+#include "time.h"
+#include "kernel.h"
#include "../net/if.h"
#include "../net/netisr.h"
#include "../net/if.h"
#include "../net/netisr.h"
#include "../vax/cpu.h"
#include "../vax/mtpr.h"
#include "../vax/cpu.h"
#include "../vax/mtpr.h"
-#include "if_uba.h"
-#include "if_dmv.h"
#include "../vaxuba/ubareg.h"
#include "../vaxuba/ubavar.h"
#include "../vaxuba/ubareg.h"
#include "../vaxuba/ubavar.h"
+#include "if_uba.h"
+#include "if_dmv.h"
-#include "../h/time.h"
-#include "../h/kernel.h"
-
-int dmvtimer; /* timer started? */
int dmv_timeout = 8; /* timeout value */
int dmv_timeout = 8; /* timeout value */
/*
* Driver information for auto-configuration stuff.
*/
int dmvprobe(), dmvattach(), dmvinit(), dmvioctl();
/*
* Driver information for auto-configuration stuff.
*/
int dmvprobe(), dmvattach(), dmvinit(), dmvioctl();
-int dmvoutput(), dmvreset();
+int dmvoutput(), dmvreset(), dmvtimeout();
struct uba_device *dmvinfo[NDMV];
u_short dmvstd[] = { 0 };
struct uba_driver dmvdriver =
struct uba_device *dmvinfo[NDMV];
u_short dmvstd[] = { 0 };
struct uba_driver dmvdriver =
/*
* Don't really know how many buffers/commands can be queued to a DMV-11.
* Manual doesn't say... Perhaps we can look at a DEC driver some day.
/*
* Don't really know how many buffers/commands can be queued to a DMV-11.
* Manual doesn't say... Perhaps we can look at a DEC driver some day.
- * These numbers ame from DMV/DMR driver.
+ * These numbers ame from DMC/DMR driver.
*/
#define NRCV 5
#define NXMT 3
#define NCMDS (NRCV+NXMT+4) /* size of command queue */
*/
#define NRCV 5
#define NXMT 3
#define NCMDS (NRCV+NXMT+4) /* size of command queue */
-#define printd if (sc->sc_if.if_flags & IFF_DEBUG) \
- printf("DMVDEBUG: dmv%d: ", unit), printf
+#ifdef DEBUG
+#define printd(f) if (sc->sc_if.if_flags & IFF_DEBUG) \
+ printf("DMVDEBUG: dmv%d: ", unit), printf(f)
+#else
+#define printd(f) /* nil */
+#endif
/* error reporting intervals */
/* error reporting intervals */
*/
struct dmv_softc {
struct ifnet sc_if; /* network-visible interface */
*/
struct dmv_softc {
struct ifnet sc_if; /* network-visible interface */
- struct dmvbufs sc_rbufs[NRCV]; /* receive buffer info */
- struct dmvbufs sc_xbufs[NXMT]; /* transmit buffer info */
- struct ifubinfo sc_ifuba; /* UNIBUS resources */
- struct ifrw sc_ifr[NRCV]; /* UNIBUS receive buffer maps */
- struct ifxmt sc_ifw[NXMT]; /* UNIBUS receive buffer maps */
short sc_oused; /* output buffers currently in use */
short sc_iused; /* input buffers given to DMV */
short sc_flag; /* flags */
short sc_oused; /* output buffers currently in use */
short sc_iused; /* input buffers given to DMV */
short sc_flag; /* flags */
- int sc_nticks; /* seconds since last interrupt */
int sc_ubinfo; /* UBA mapping info for base table */
int sc_errors[8]; /* error counters */
#define sc_rte sc_errors[0] /* receive threshhold error */
int sc_ubinfo; /* UBA mapping info for base table */
int sc_errors[8]; /* error counters */
#define sc_rte sc_errors[0] /* receive threshhold error */
#define sc_qovf sc_errors[5] /* command/response queue overflow */
#define sc_cxrl sc_errors[6] /* carrier loss */
#define sc_unknown sc_errors[7] /* other errors - look in DMV manual */
#define sc_qovf sc_errors[5] /* command/response queue overflow */
#define sc_cxrl sc_errors[6] /* carrier loss */
#define sc_unknown sc_errors[7] /* other errors - look in DMV manual */
+ struct dmvbufs sc_rbufs[NRCV]; /* receive buffer info */
+ struct dmvbufs sc_xbufs[NXMT]; /* transmit buffer info */
+ struct ifubinfo sc_ifuba; /* UNIBUS resources */
+ struct ifrw sc_ifr[NRCV]; /* UNIBUS receive buffer maps */
+ struct ifxmt sc_ifw[NXMT]; /* UNIBUS receive buffer maps */
/* command queue stuff */
struct dmv_command sc_cmdbuf[NCMDS];
struct dmv_command *sc_qhead; /* head of command queue */
/* command queue stuff */
struct dmv_command sc_cmdbuf[NCMDS];
struct dmv_command *sc_qhead; /* head of command queue */
} dmv_softc[NDMV];
/* flags */
} dmv_softc[NDMV];
/* flags */
-#define DMV_ALLOC 0x01 /* unibus resources allocated */
-#define DMV_RESTART 0x04 /* software restart in progress */
-#define DMV_ACTIVE 0x08 /* device active */
-#define DMV_RUNNING 0x20 /* device initialized */
+#define DMV_RESTART 0x01 /* software restart in progress */
+#define DMV_ONLINE 0x02 /* device managed to transmit */
+#define DMV_RUNNING 0x04 /* device initialized */
/* queue manipulation macros */
/* queue manipulation macros */
addr->bsel1 = DMV_MCLR;
for (i = 100000; i && (addr->bsel1 & DMV_RUN) == 0; i--)
;
addr->bsel1 = DMV_MCLR;
for (i = 100000; i && (addr->bsel1 & DMV_RUN) == 0; i--)
;
+ br = 0x15; /* screwy interrupt structure */
sc->sc_if.if_output = dmvoutput;
sc->sc_if.if_ioctl = dmvioctl;
sc->sc_if.if_reset = dmvreset;
sc->sc_if.if_output = dmvoutput;
sc->sc_if.if_ioctl = dmvioctl;
sc->sc_if.if_reset = dmvreset;
+ sc->sc_if.if_watchdog = dmvtimeout;
sc->sc_if.if_flags = IFF_POINTOPOINT;
sc->sc_ifuba.iff_flags = UBA_CANTWAIT;
sc->sc_if.if_flags = IFF_POINTOPOINT;
sc->sc_ifuba.iff_flags = UBA_CANTWAIT;
- if (dmvtimer == 0) {
- dmvtimer = 1;
- timeout(dmvwatch, (caddr_t) 0, hz);
- }
ifp->if_flags &= ~IFF_UP;
return;
}
ifp->if_flags &= ~IFF_UP;
return;
}
/* initialize UNIBUS resources */
sc->sc_iused = sc->sc_oused = 0;
if ((ifp->if_flags & IFF_RUNNING) == 0) {
/* initialize UNIBUS resources */
sc->sc_iused = sc->sc_oused = 0;
if ((ifp->if_flags & IFF_RUNNING) == 0) {
}
ifp->if_flags |= IFF_RUNNING;
}
}
ifp->if_flags |= IFF_RUNNING;
}
+ /*
+ * Limit packets enqueued until we see if we're on the air.
+ */
+ ifp->if_snd.ifq_maxlen = 3;
+
/* initialize buffer pool */
/* receives */
/* initialize buffer pool */
/* receives */
dmvload( sc, DMV_CNTRLI, (QP_TRIB|QP_SEL6), 1, 0, DMV_ESTTRIB,0);
dmvload( sc, DMV_CNTRLI, (QP_TRIB|QP_SEL6), 1, 0, DMV_REQSUS,0);
sc->sc_flag |= (DMV_RESTART|DMV_RUNNING);
dmvload( sc, DMV_CNTRLI, (QP_TRIB|QP_SEL6), 1, 0, DMV_ESTTRIB,0);
dmvload( sc, DMV_CNTRLI, (QP_TRIB|QP_SEL6), 1, 0, DMV_REQSUS,0);
sc->sc_flag |= (DMV_RESTART|DMV_RUNNING);
- sc->sc_flag &= ~DMV_ACTIVE;
+ sc->sc_flag &= ~DMV_ONLINE;
addr->bsel0 |= DMV_IEO;
}
addr->bsel0 |= DMV_IEO;
}
* Dequeue up to NXMT requests and map them to the UNIBUS.
* If no more requests, or no dmv buffers available, just return.
*/
* Dequeue up to NXMT requests and map them to the UNIBUS.
* If no more requests, or no dmv buffers available, just return.
*/
+ printd(("dmvstart\n"));
n = 0;
for (rp = &sc->sc_xbufs[0]; rp < &sc->sc_xbufs[NXMT]; rp++ ) {
/* find an available buffer */
n = 0;
for (rp = &sc->sc_xbufs[0]; rp < &sc->sc_xbufs[NXMT]; rp++ ) {
/* find an available buffer */
* and start the output.
*/
rp->cc = if_ubaput(&sc->sc_ifuba, &sc->sc_ifw[n], m);
* and start the output.
*/
rp->cc = if_ubaput(&sc->sc_ifuba, &sc->sc_ifw[n], m);
+ if (++sc->sc_oused == 1)
+ sc->sc_if.if_timer = dmv_timeout;
register struct dmv_command *qp;
unit = sc - dmv_softc;
register struct dmv_command *qp;
unit = sc - dmv_softc;
- printd("dmvload: cmd=%x mask=%x trib=%x sel4=%x sel6=%x sel10=%x\n",
+ printd(("dmvload: cmd=%x mask=%x trib=%x sel4=%x sel6=%x sel10=%x\n",
(unsigned) cmd,
(unsigned) mask,
(unsigned) tributary,
(unsigned) sel4,
(unsigned) sel6,
(unsigned) sel10
(unsigned) cmd,
(unsigned) mask,
(unsigned) tributary,
(unsigned) sel4,
(unsigned) sel6,
(unsigned) sel10
addr = (struct dmvdevice *)dmvinfo[unit]->ui_addr;
sps = spl5();
addr = (struct dmvdevice *)dmvinfo[unit]->ui_addr;
sps = spl5();
addr = (struct dmvdevice *)dmvinfo[unit]->ui_addr;
sc = &dmv_softc[unit];
addr = (struct dmvdevice *)dmvinfo[unit]->ui_addr;
sc = &dmv_softc[unit];
if ((qp = sc->sc_qactive) == (struct dmv_command *) 0) {
log(LOG_WARNING, "dmvrint: dmv%d no command\n", unit);
return;
if ((qp = sc->sc_qactive) == (struct dmv_command *) 0) {
log(LOG_WARNING, "dmvrint: dmv%d no command\n", unit);
return;
register struct dmvbufs *rp;
register struct ifxmt *ifxp;
struct dmv_header *dh;
register struct dmvbufs *rp;
register struct ifxmt *ifxp;
struct dmv_header *dh;
addr = (struct dmvdevice *)ui->ui_addr;
sc = &dmv_softc[unit];
addr = (struct dmvdevice *)ui->ui_addr;
sc = &dmv_softc[unit];
sel10 = addr->wsel10;
addr->bsel2 &= ~DMV_RDO;
pkaddr = sel4 | ((sel6 & 0x3f) << 16);
sel10 = addr->wsel10;
addr->bsel2 &= ~DMV_RDO;
pkaddr = sel4 | ((sel6 & 0x3f) << 16);
- printd("dmvxint: sel2=%x sel4=%x sel6=%x sel10=%x pkaddr=%x\n",
+ printd(("dmvxint: sel2=%x sel4=%x sel6=%x sel10=%x pkaddr=%x\n",
(unsigned) sel2,
(unsigned) sel4,
(unsigned) sel6,
(unsigned) sel10,
(unsigned) pkaddr
(unsigned) sel2,
(unsigned) sel4,
(unsigned) sel6,
(unsigned) sel10,
(unsigned) pkaddr
if((sc->sc_flag & DMV_RUNNING)==0) {
log(LOG_WARNING, "dmvxint: dmv%d xint while down\n", unit);
return;
if((sc->sc_flag & DMV_RUNNING)==0) {
log(LOG_WARNING, "dmvxint: dmv%d xint while down\n", unit);
return;
ifxp->ifw_xtofree = 0;
}
rp->flags &= ~DBUF_DMVS;
ifxp->ifw_xtofree = 0;
}
rp->flags &= ~DBUF_DMVS;
- sc->sc_oused--;
- sc->sc_nticks = 0;
- sc->sc_flag |= DMV_ACTIVE;
+ if (--sc->sc_oused == 0)
+ sc->sc_if.if_timer = 0;
+ else
+ sc->sc_if.if_timer = dmv_timeout;
+ if ((sc->sc_flag & DMV_ONLINE) == 0) {
+ extern int ifqmaxlen;
+
+ /*
+ * We're on the air.
+ * Open the queue to the usual value.
+ */
+ sc->sc_flag |= DMV_ONLINE;
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+ }
break;
case DMV_CNTRLO:
/* ACCUMULATE STATISTICS */
break;
case DMV_CNTRLO:
/* ACCUMULATE STATISTICS */
switch(sel6&DMV_EEC) {
case DMV_ORUN:
if(sc->sc_flag & DMV_RESTART) {
load_rec_bufs(sc);
sc->sc_flag &= ~DMV_RESTART;
log(LOG_INFO,
switch(sel6&DMV_EEC) {
case DMV_ORUN:
if(sc->sc_flag & DMV_RESTART) {
load_rec_bufs(sc);
sc->sc_flag &= ~DMV_RESTART;
log(LOG_INFO,
- "dmvxint: dmv%d far end on-line\n",
- unit
- );
+ "dmv%d: far end on-line\n", unit);
} else {
log(LOG_WARNING,
} else {
log(LOG_WARNING,
- "dmvxint: dmv%d far end restart\n",
- unit
- );
- goto fatal;
+ "dmv%d: far end restart\n", unit);
+ goto restart;
}
break;
case DMV_RTE:
ifp->if_ierrors++;
if ((sc->sc_rte++ % DMV_RPRTE) == 0)
log(LOG_WARNING,
}
break;
case DMV_RTE:
ifp->if_ierrors++;
if ((sc->sc_rte++ % DMV_RPRTE) == 0)
log(LOG_WARNING,
- "dmvxint: dmv%d receive threshold error\n",
+ "dmv%d: receive threshold error\n",
unit);
break;
case DMV_TTE:
ifp->if_oerrors++;
if ((sc->sc_xte++ % DMV_RPTTE) == 0)
log(LOG_WARNING,
unit);
break;
case DMV_TTE:
ifp->if_oerrors++;
if ((sc->sc_xte++ % DMV_RPTTE) == 0)
log(LOG_WARNING,
- "dmvxint: dmv%d transmit threshold error\n",
+ "dmv%d: transmit threshold error\n",
unit);
break;
case DMV_STE:
if ((sc->sc_ste++ % DMV_RPSTE) == 0)
log(LOG_WARNING,
unit);
break;
case DMV_STE:
if ((sc->sc_ste++ % DMV_RPSTE) == 0)
log(LOG_WARNING,
- "dmvxint: dmv%d select threshold error\n",
+ "dmv%d: select threshold error\n",
unit);
break;
case DMV_NXM:
if ((sc->sc_nxm++ % DMV_RPNXM) == 0)
log(LOG_WARNING,
unit);
break;
case DMV_NXM:
if ((sc->sc_nxm++ % DMV_RPNXM) == 0)
log(LOG_WARNING,
- "dmvxint: dmv%d nonexistent memory error\n",
+ "dmv%d: nonexistent memory error\n",
unit);
break;
case DMV_MODD:
unit);
break;
case DMV_MODD:
- if ((sc->sc_modd++ % DMV_RPMODD) == 0)
+ if ((sc->sc_modd++ % DMV_RPMODD) == 0) {
- "dmvxint: dmv%d modem disconnected error\n",
+ "dmv%d: modem disconnected error\n",
break;
case DMV_CXRL:
if ((sc->sc_cxrl++ % DMV_RPCXRL) == 0)
log(LOG_WARNING,
break;
case DMV_CXRL:
if ((sc->sc_cxrl++ % DMV_RPCXRL) == 0)
log(LOG_WARNING,
- "dmvxint: dmv%d carrier loss error\n",
+ "dmv%d: carrier loss error\n",
unit);
break;
case DMV_QOVF:
log(LOG_WARNING,
unit);
break;
case DMV_QOVF:
log(LOG_WARNING,
- "dmvxint: dmv%d response queue overflow\n",
- unit
- );
+ "dmv%d: response queue overflow\n",
+ unit);
default:
log(LOG_WARNING,
default:
log(LOG_WARNING,
- "dmvxint: dmv%d unknown error %o\n",
- unit,
- sel6&DMV_EEC
- );
+ "dmv%d: unknown error %o\n",
+ unit, sel6&DMV_EEC);
if ((sc->sc_unknown++ % DMV_RPUNKNOWN) == 0)
if ((sc->sc_unknown++ % DMV_RPUNKNOWN) == 0)
case DMV_BDXSN:
case DMV_BDXNS:
log(LOG_INFO,
case DMV_BDXSN:
case DMV_BDXNS:
log(LOG_INFO,
- "dmvxint: dmv%d buffer disp for halted trib %o\n",
+ "dmv%d: buffer disp for halted trib %o\n",
case DMV_MDEFO:
if((sel6&0x1f) == 020) {
log(LOG_INFO,
case DMV_MDEFO:
if((sel6&0x1f) == 020) {
log(LOG_INFO,
- "dmvxint: dmv%d buffer return complete sel3=%x\n",
+ "dmv%d: buffer return complete sel3=%x\n",
unit, sel3);
} else {
log(LOG_INFO,
unit, sel3);
} else {
log(LOG_INFO,
- "dmvxint: dmv%d info resp sel3=%x sel4=%x sel6=%x\n",
+ "dmv%d: info resp sel3=%x sel4=%x sel6=%x\n",
unit, sel3, sel4, sel6
);
}
break;
default:
unit, sel3, sel4, sel6
);
}
break;
default:
- log(LOG_WARNING,
- "dmvxint: dmv%d bad control %o\n",
+ log(LOG_WARNING, "dmv%d: bad control %o\n",
}
dmvstart(unit);
return;
}
dmvstart(unit);
return;
-fatal:
- log(
- LOG_ERR,
- "dmv%d: fatal error, output code ==%o\n",
- unit,
- sel6&DMV_EEC
- );
load_rec_bufs(sc)
register struct dmv_softc *sc;
{
load_rec_bufs(sc)
register struct dmv_softc *sc;
{
register struct dmv_header *dh;
register int off;
register struct dmv_header *dh;
register int off;
+ if ((ifp->if_flags & IFF_UP) == 0) {
+ error = ENETDOWN;
+ goto bad;
+ }
+
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
- log(LOG_ERR, "dmvoutput, dmv%d can't handle af%d\n", ifp->if_unit,
- dst->sa_family);
+ log(LOG_ERR, "dmvoutput, dmv%d can't handle af%d\n",
+ ifp->if_unit, dst->sa_family);
error = EAFNOSUPPORT;
goto bad;
}
error = EAFNOSUPPORT;
goto bad;
}
case SIOCSIFFLAGS:
if ((ifp->if_flags & IFF_UP) == 0 &&
case SIOCSIFFLAGS:
if ((ifp->if_flags & IFF_UP) == 0 &&
- sc->sc_flag & DMV_RUNNING) {
- ((struct dmvdevice *)
- (dmvinfo[ifp->if_unit]->ui_addr))->bsel1 = DMV_MCLR;
- for(;;) {
- IF_DEQUEUE(&sc->sc_if.if_snd, m);
- if (m != NULL)
- m_freem(m);
- else
- break;
- }
- sc->sc_flag &= ~DMV_RUNNING;
- } else if (ifp->if_flags & IFF_UP &&
+ sc->sc_flag & DMV_RUNNING)
+ dmvdown(ifp->if_unit);
+ else if (ifp->if_flags & IFF_UP &&
(sc->sc_flag & DMV_RUNNING) == 0)
dmvrestart(ifp->if_unit);
break;
(sc->sc_flag & DMV_RUNNING) == 0)
dmvrestart(ifp->if_unit);
break;
dmvrestart(unit)
int unit;
{
dmvrestart(unit)
int unit;
{
- register struct dmv_softc *sc = &dmv_softc[unit];
- register struct uba_device *ui = dmvinfo[unit];
register struct dmvdevice *addr;
register struct dmvdevice *addr;
- register struct ifxmt *ifxp;
-
-#ifdef notdef
- addr = (struct dmvdevice *)ui->ui_addr;
+
+ dmvdown(unit);
+
+ addr = (struct dmvdevice *)(dmvinfo[unit]->ui_addr);
- * Let the DMR finish the MCLR. At 1 Mbit, it should do so
- * in about a max of 6.4 milliseconds with diagnostics enabled.
+ * Let the DMV finish the MCLR.
- addr->bsel1 = DMV_MCLR;
for (i = 100000; i && (addr->bsel1 & DMV_RUN) == 0; i--)
;
if ((addr->bsel1 & DMV_RUN) == 0) {
for (i = 100000; i && (addr->bsel1 & DMV_RUN) == 0; i--)
;
if ((addr->bsel1 & DMV_RUN) == 0) {
}
if ((addr->bsel4 != 033) || (addr->bsel6 != 0305))
{
}
if ((addr->bsel4 != 033) || (addr->bsel6 != 0305))
{
- log(LOG_ERR, "dmvrestart: device init failed, bsel4=%o, bsel6=%o\n",
- addr->bsel4, addr->bsel6);
+ log(LOG_ERR, "dmv%d: device init failed, bsel4=%o, bsel6=%o\n",
+ unit, addr->bsel4, addr->bsel6);
+
+ /* restart DMV */
+ dmvinit(unit);
+ dmv_softc[unit].sc_if.if_collisions++; /* why not? */
+}
+
+/*
+ * Reset a device and mark down.
+ * Flush output queue and drop queue limit.
+ */
+dmvdown(unit)
+ int unit;
+{
+ struct dmv_softc *sc = &dmv_softc[unit];
+ register struct ifxmt *ifxp;
+
+ ((struct dmvdevice *)(dmvinfo[unit]->ui_addr))->bsel1 = DMV_MCLR;
+ sc->sc_flag &= ~(DMV_RUNNING | DMV_ONLINE);
+
for (ifxp = sc->sc_ifw; ifxp < &sc->sc_ifw[NXMT]; ifxp++) {
if (ifxp->ifw_xtofree) {
(void) m_freem(ifxp->ifw_xtofree);
ifxp->ifw_xtofree = 0;
}
}
for (ifxp = sc->sc_ifw; ifxp < &sc->sc_ifw[NXMT]; ifxp++) {
if (ifxp->ifw_xtofree) {
(void) m_freem(ifxp->ifw_xtofree);
ifxp->ifw_xtofree = 0;
}
}
- /* restart DMV */
- dmvinit(unit);
- sc->sc_if.if_collisions++; /* why not? */
+ sc->sc_oused = 0;
+ if_qflush(&sc->sc_if.if_snd);
+
+ /*
+ * Limit packets enqueued until we're back on the air.
+ */
+ sc->sc_if.if_snd.ifq_maxlen = 3;
- * Check to see that transmitted packets don't
- * lose interrupts. The device has to be active.
+ * Watchdog timeout to see that transmitted packets don't
+ * lose interrupts. The device has to be online.
+dmvtimeout(unit)
+ int unit;
- register struct uba_device *ui;
register struct dmv_softc *sc;
struct dmvdevice *addr;
register struct dmv_softc *sc;
struct dmvdevice *addr;
- for (i = 0; i < NDMV; i++) {
- sc = &dmv_softc[i];
- if ((sc->sc_flag & DMV_ACTIVE) == 0)
- continue;
- if ((ui = dmvinfo[i]) == 0 || ui->ui_alive == 0)
- continue;
- if (sc->sc_oused) {
- sc->sc_nticks++;
- if (sc->sc_nticks > dmv_timeout) {
- sc->sc_nticks = 0;
- addr = (struct dmvdevice *)ui->ui_addr;
- log(LOG_ERR, "dmv%d hung: bsel0=%b bsel2=%b\n",
- i, addr->bsel0 & 0xff, DMV0BITS,
- addr->bsel2 & 0xff, DMV2BITS);
- dmvrestart(i);
- }
- }
+ sc = &dmv_softc[unit];
+ if (sc->sc_flag & DMV_ONLINE) {
+ addr = (struct dmvdevice *)(dmvinfo[unit]->ui_addr);
+ log(LOG_ERR, "dmv%d: output timeout, bsel0=%b bsel2=%b\n",
+ unit, addr->bsel0 & 0xff, DMV0BITS,
+ addr->bsel2 & 0xff, DMV2BITS);
+ dmvrestart(unit);
- timeout(dmvwatch, (caddr_t) 0, hz);