remember dma count, as can't calculate correctly on Emulex;
[unix-history] / usr / src / sys / vax / uba / dz.c
index ce5cd81..1e35f9a 100644 (file)
@@ -1,30 +1,42 @@
-/*     dz.c    4.44    82/10/10        */
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)dz.c        6.11 (Berkeley) %G%
+ */
 
 #include "dz.h"
 #if NDZ > 0
 /*
 
 #include "dz.h"
 #if NDZ > 0
 /*
- *  DZ-11 and DZ32 Driver
+ *  DZ-11/DZ-32 Driver
  *
  * This driver mimics dh.c; see it for explanation of common code.
  */
 #include "bk.h"
  *
  * This driver mimics dh.c; see it for explanation of common code.
  */
 #include "bk.h"
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/tty.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/proc.h"
-#include "../h/map.h"
-#include "../h/pte.h"
-#include "../h/buf.h"
-#include "../h/vm.h"
-#include "../h/conf.h"
-#include "../h/bk.h"
-#include "../h/file.h"
-#include "../h/uio.h"
-
-#include "../vaxuba/pdma.h"
-#include "../vaxuba/ubavar.h"
+
+#include "../machine/pte.h"
+
+#include "param.h"
+#include "systm.h"
+#include "ioctl.h"
+#include "tty.h"
+#include "dir.h"
+#include "user.h"
+#include "proc.h"
+#include "map.h"
+#include "buf.h"
+#include "vm.h"
+#include "conf.h"
+#include "bkmac.h"
+#include "file.h"
+#include "uio.h"
+#include "kernel.h"
+#include "syslog.h"
+
+#include "pdma.h"
+#include "ubavar.h"
+#include "dzreg.h"
 
 /*
  * Driver information for auto-configuration stuff.
 
 /*
  * Driver information for auto-configuration stuff.
@@ -36,95 +48,19 @@ struct      uba_driver dzdriver =
        { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo };
 
 #define        NDZLINE         (NDZ*8)
        { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo };
 
 #define        NDZLINE         (NDZ*8)
-/*
- * Registers and bits
- */
-
-/* bits in dzlpr */
-#define        BITS7   0020
-#define        BITS8   0030
-#define        TWOSB   0040
-#define        PENABLE 0100
-#define        OPAR    0200
-
-/* bits in dzrbuf */
-#define        DZ_PE   010000
-#define        DZ_FE   020000
-#define        DZ_DO   040000
-
-/* bits in dzcsr */
-#define        DZ_32   000001          /* DZ32 mode */
-#define        DZ_MIE  000002          /* Modem Interrupt Enable */
-#define        DZ_CLR  000020          /* Reset dz */
-#define        DZ_MSE  000040          /* Master Scan Enable */
-#define        DZ_RIE  000100          /* Receiver Interrupt Enable */
-#define DZ_MSC 004000          /* Modem Status Change */
-#define        DZ_SAE  010000          /* Silo Alarm Enable */
-#define        DZ_TIE  040000          /* Transmit Interrupt Enable */
-#define        DZ_IEN  (DZ_32|DZ_MIE|DZ_MSE|DZ_RIE|DZ_TIE|DZ_SAE)
-
-/* flags for modem-control */
-#define        DZ_ON   DZ_DTR
-#define        DZ_OFF  0
-
-/* bits in dzlcs */
-#define DZ_ACK 0100000         /* ACK bit in dzlcs */
-#define DZ_RTS 0010000         /* Request To Send */
-#define        DZ_ST   0004000         /* Secondary Transmit */
-#define        DZ_BRK  0002000         /* Break */
-#define DZ_DTR 0001000         /* Data Terminal Ready */
-#define        DZ_LE   0000400         /* Line Enable */
-#define        DZ_DSR  0000200         /* Data Set Ready */
-#define        DZ_RI   0000100         /* Ring Indicate */
-#define DZ_CD  0000040         /* Carrier Detect */
-#define        DZ_CTS  0000020         /* Clear To Send */
-#define        DZ_SR   0000010         /* Secondary Receive */
-/* bits in dm lsr, copied from dh.c */
-#define        DML_DSR         0000400         /* data set ready, not a real DM bit */
-#define        DML_RNG         0000200         /* ring */
-#define        DML_CAR         0000100         /* carrier detect */
-#define        DML_CTS         0000040         /* clear to send */
-#define        DML_SR          0000020         /* secondary receive */
-#define        DML_ST          0000010         /* secondary transmit */
-#define        DML_RTS         0000004         /* request to send */
-#define        DML_DTR         0000002         /* data terminal ready */
-#define        DML_LE          0000001         /* line enable */
+#define        FASTTIMER       (hz/30)         /* rate to drain silos, when in use */
 
 int    dzstart(), dzxint(), dzdma();
 int    ttrstrt();
 struct tty dz_tty[NDZLINE];
 int    dz_cnt = { NDZLINE };
 int    dzact;
 
 int    dzstart(), dzxint(), dzdma();
 int    ttrstrt();
 struct tty dz_tty[NDZLINE];
 int    dz_cnt = { NDZLINE };
 int    dzact;
-
-struct device {
-       short dzcsr;
-       short dzrbuf;
-       union {
-               struct {
-                       char    dztcr0;
-                       char    dzdtr0;
-                       char    dztbuf0;
-                       char    dzbrk0;
-               } dz11;
-               struct {
-                       short   dzlcs0;
-                       char    dztbuf0;
-                       char    dzlnen0;
-               } dz32;
-       } dzun;
-};
-
-#define dzlpr  dzrbuf
-#define dzmsr  dzun.dz11.dzbrk0
-#define dztcr  dzun.dz11.dztcr0
-#define dzdtr  dzun.dz11.dzdtr0
-#define dztbuf dzun.dz11.dztbuf0
-#define dzlcs  dzun.dz32.dzlcs0
-#define        dzbrk   dzmsr
-#define dzlnen dzun.dz32.dzlnen0
-#define dzmtsr dzun.dz32.dztbuf0
+int    dzsilos;                        /* mask of dz's with silo in use */
+int    dzchars[NDZ];                   /* recent input count */
+int    dzrate[NDZ];                    /* smoothed input count */
+int    dztimerintvl;                   /* time interval for dztimer */
+int    dzhighrate = 100;               /* silo on if dzchars > dzhighrate */
+int    dzlowrate = 75;                 /* silo off if dzrate < dzlowrate */
 
 #define dzwait(x)      while (((x)->dzlcs & DZ_ACK) == 0)
 
 
 #define dzwait(x)      while (((x)->dzlcs & DZ_ACK) == 0)
 
@@ -149,8 +85,8 @@ struct       pdma dzpdma[NDZLINE];
 char   dz_speeds[] =
        { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 };
  
 char   dz_speeds[] =
        { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 };
  
-#ifndef PORTSELECTOR
-#define        ISPEED  B300
+#ifndef        PORTSELECTOR
+#define        ISPEED  B9600
 #define        IFLAGS  (EVENP|ODDP|ECHO)
 #else
 #define        ISPEED  B4800
 #define        IFLAGS  (EVENP|ODDP|ECHO)
 #else
 #define        ISPEED  B4800
@@ -161,7 +97,7 @@ dzprobe(reg)
        caddr_t reg;
 {
        register int br, cvec;
        caddr_t reg;
 {
        register int br, cvec;
-       register struct device *dzaddr = (struct device *)reg;
+       register struct dzdevice *dzaddr = (struct dzdevice *)reg;
 
 #ifdef lint
        br = 0; cvec = br; br = cvec;
 
 #ifdef lint
        br = 0; cvec = br; br = cvec;
@@ -176,7 +112,7 @@ dzprobe(reg)
        dzaddr->dzcsr = DZ_CLR|DZ_32;           /* reset everything */
        if (cvec && cvec != 0x200)
                cvec -= 4;
        dzaddr->dzcsr = DZ_CLR|DZ_32;           /* reset everything */
        if (cvec && cvec != 0x200)
                cvec -= 4;
-       return (sizeof (struct device));
+       return (sizeof (struct dzdevice));
 }
 
 dzattach(ui)
 }
 
 dzattach(ui)
@@ -188,7 +124,7 @@ dzattach(ui)
        extern dzscan();
 
        for (cntr = 0; cntr < 8; cntr++) {
        extern dzscan();
 
        for (cntr = 0; cntr < 8; cntr++) {
-               pdp->p_addr = (struct device *)ui->ui_addr;
+               pdp->p_addr = (struct dzdevice *)ui->ui_addr;
                pdp->p_arg = (int)tp;
                pdp->p_fcn = dzxint;
                pdp++, tp++;
                pdp->p_arg = (int)tp;
                pdp->p_fcn = dzxint;
                pdp++, tp++;
@@ -197,6 +133,7 @@ dzattach(ui)
        if (dz_timer == 0) {
                dz_timer++;
                timeout(dzscan, (caddr_t)0, hz);
        if (dz_timer == 0) {
                dz_timer++;
                timeout(dzscan, (caddr_t)0, hz);
+               dztimerintvl = FASTTIMER;
        }
 }
 
        }
 }
 
@@ -208,24 +145,27 @@ dzopen(dev, flag)
        register int unit;
  
        unit = minor(dev);
        register int unit;
  
        unit = minor(dev);
-       if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) {
-               u.u_error = ENXIO;
-               return;
-       }
+       if (unit >= dz_cnt || dzpdma[unit].p_addr == 0)
+               return (ENXIO);
        tp = &dz_tty[unit];
        tp->t_addr = (caddr_t)&dzpdma[unit];
        tp->t_oproc = dzstart;
        tp = &dz_tty[unit];
        tp->t_addr = (caddr_t)&dzpdma[unit];
        tp->t_oproc = dzstart;
-       tp->t_state |= TS_WOPEN;
        if ((tp->t_state & TS_ISOPEN) == 0) {
                ttychars(tp);
        if ((tp->t_state & TS_ISOPEN) == 0) {
                ttychars(tp);
-               tp->t_ospeed = tp->t_ispeed = ISPEED;
-               tp->t_flags = IFLAGS;
-               /* tp->t_state |= TS_HUPCLS; */
+#ifndef PORTSELECTOR
+               if (tp->t_ispeed == 0) {
+#else
+                       tp->t_state |= TS_HUPCLS;
+#endif PORTSELECTOR
+                       tp->t_ispeed = ISPEED;
+                       tp->t_ospeed = ISPEED;
+                       tp->t_flags = IFLAGS;
+#ifndef PORTSELECTOR
+               }
+#endif PORTSELECTOR
                dzparam(unit);
                dzparam(unit);
-       } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) {
-               u.u_error = EBUSY;
-               return;
-       }
+       } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
+               return (EBUSY);
        (void) dzmctl(dev, DZ_ON, DMSET);
        (void) spl5();
        while ((tp->t_state & TS_CARR_ON) == 0) {
        (void) dzmctl(dev, DZ_ON, DMSET);
        (void) spl5();
        while ((tp->t_state & TS_CARR_ON) == 0) {
@@ -233,7 +173,7 @@ dzopen(dev, flag)
                sleep((caddr_t)&tp->t_rawq, TTIPRI);
        }
        (void) spl0();
                sleep((caddr_t)&tp->t_rawq, TTIPRI);
        }
        (void) spl0();
-       (*linesw[tp->t_line].l_open)(dev, tp);
+       return ((*linesw[tp->t_line].l_open)(dev, tp));
 }
  
 /*ARGSUSED*/
 }
  
 /*ARGSUSED*/
@@ -242,7 +182,7 @@ dzclose(dev, flag)
 {
        register struct tty *tp;
        register int unit;
 {
        register struct tty *tp;
        register int unit;
-       register struct device *dzaddr;
+       register struct dzdevice *dzaddr;
        int dz;
  
        unit = minor(dev);
        int dz;
  
        unit = minor(dev);
@@ -276,7 +216,7 @@ dzwrite(dev, uio)
        register struct tty *tp;
  
        tp = &dz_tty[minor(dev)];
        register struct tty *tp;
  
        tp = &dz_tty[minor(dev)];
-       (*linesw[tp->t_line].l_write)(tp, uio);
+       return ((*linesw[tp->t_line].l_write)(tp, uio));
 }
  
 /*ARGSUSED*/
 }
  
 /*ARGSUSED*/
@@ -285,7 +225,7 @@ dzrint(dz)
 {
        register struct tty *tp;
        register int c;
 {
        register struct tty *tp;
        register int c;
-       register struct device *dzaddr;
+       register struct dzdevice *dzaddr;
        register struct tty *tp0;
        register int unit;
        int overrun = 0;
        register struct tty *tp0;
        register int unit;
        int overrun = 0;
@@ -306,21 +246,13 @@ dzrint(dz)
                dzwait(dzaddr);         /* wait for them */
                if (c & DZ_CD)          /* carrier status change? */
                if (dzaddr->dzlcs & DZ_CD) {    /* carrier up? */
                dzwait(dzaddr);         /* wait for them */
                if (c & DZ_CD)          /* carrier status change? */
                if (dzaddr->dzlcs & DZ_CD) {    /* carrier up? */
-                       if ((tp->t_state&TS_CARR_ON) == 0) {
-                               wakeup((caddr_t)&tp->t_rawq);
-                               tp->t_state |= TS_CARR_ON;
-                       }
-               } else {        /* no carrier */
-                       if (tp->t_state&TS_CARR_ON) {
-                               gsignal(tp->t_pgrp, SIGHUP);
-                               gsignal(tp->t_pgrp, SIGCONT);
-                               dzaddr->dzlcs = DZ_ACK|(c&7);
-                               flushtty(tp, FREAD|FWRITE);
-                       }
-                       tp->t_state &= ~TS_CARR_ON;
-               }
+                       /* carrier present */
+                       (void)(*linesw[tp->t_line].l_modem)(tp, 1);
+               } else if ((*linesw[tp->t_line].l_modem)(tp, 0) == 0)
+                       dzaddr->dzlcs = DZ_ACK|(c&7);
        }
        while ((c = dzaddr->dzrbuf) < 0) {      /* char present */
        }
        while ((c = dzaddr->dzrbuf) < 0) {      /* char present */
+               dzchars[dz]++;
                tp = tp0 + ((c>>8)&07);
                if (tp >= &dz_tty[dz_cnt])
                        continue;
                tp = tp0 + ((c>>8)&07);
                if (tp >= &dz_tty[dz_cnt])
                        continue;
@@ -329,15 +261,15 @@ dzrint(dz)
 #ifdef PORTSELECTOR
                        if ((tp->t_state&TS_WOPEN) == 0)
 #endif
 #ifdef PORTSELECTOR
                        if ((tp->t_state&TS_WOPEN) == 0)
 #endif
-                       continue;
+                               continue;
                }
                if (c&DZ_FE)
                        if (tp->t_flags & RAW)
                                c = 0;
                        else
                }
                if (c&DZ_FE)
                        if (tp->t_flags & RAW)
                                c = 0;
                        else
-                               c = tun.t_intrc;
+                               c = tp->t_intrc;
                if (c&DZ_DO && overrun == 0) {
                if (c&DZ_DO && overrun == 0) {
-                       /* printf("dz%d,%d: silo overflow\n", dz, (c>>8)&7); */
+                       log(LOG_WARNING, "dz%d,%d: silo overflow\n", dz, (c>>8)&7);
                        overrun = 1;
                }
                if (c&DZ_PE)    
                        overrun = 1;
                }
                if (c&DZ_PE)    
@@ -362,16 +294,21 @@ dzioctl(dev, cmd, data, flag)
        register struct tty *tp;
        register int unit = minor(dev);
        register int dz = unit >> 3;
        register struct tty *tp;
        register int unit = minor(dev);
        register int dz = unit >> 3;
-       register struct device *dzaddr;
+       register struct dzdevice *dzaddr;
+       int error;
  
        tp = &dz_tty[unit];
  
        tp = &dz_tty[unit];
-       cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
-       if (cmd == 0)
-               return;
-       if (ttioctl(tp, cmd, data, flag)) {
-               if (cmd == TIOCSETP || cmd == TIOCSETN)
+       error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
+       if (error >= 0)
+               return (error);
+       error = ttioctl(tp, cmd, data, flag);
+       if (error >= 0) {
+               if (cmd == TIOCSETP || cmd == TIOCSETN || cmd == TIOCLBIS ||
+                   cmd == TIOCLBIC || cmd == TIOCLSET)
                        dzparam(unit);
                        dzparam(unit);
-       } else switch(cmd) {
+               return (error);
+       }
+       switch (cmd) {
 
        case TIOCSBRK:
                dzaddr = ((struct pdma *)(tp->t_addr))->p_addr;
 
        case TIOCSBRK:
                dzaddr = ((struct pdma *)(tp->t_addr))->p_addr;
@@ -414,8 +351,9 @@ dzioctl(dev, cmd, data, flag)
                break;
 
        default:
                break;
 
        default:
-               u.u_error = ENOTTY;
+               return (ENOTTY);
        }
        }
+       return (0);
 }
 
 dmtodz(bits)
 }
 
 dmtodz(bits)
@@ -448,19 +386,22 @@ dzparam(unit)
        register int unit;
 {
        register struct tty *tp;
        register int unit;
 {
        register struct tty *tp;
-       register struct device *dzaddr;
+       register struct dzdevice *dzaddr;
        register int lpr;
  
        tp = &dz_tty[unit];
        dzaddr = dzpdma[unit].p_addr;
        register int lpr;
  
        tp = &dz_tty[unit];
        dzaddr = dzpdma[unit].p_addr;
-       dzaddr->dzcsr = DZ_IEN;
+       if (dzsilos & (1 << (unit >> 3)))
+               dzaddr->dzcsr = DZ_IEN | DZ_SAE;
+       else
+               dzaddr->dzcsr = DZ_IEN;
        dzact |= (1<<(unit>>3));
        if (tp->t_ispeed == 0) {
                (void) dzmctl(unit, DZ_OFF, DMSET);     /* hang up line */
                return;
        }
        lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07);
        dzact |= (1<<(unit>>3));
        if (tp->t_ispeed == 0) {
                (void) dzmctl(unit, DZ_OFF, DMSET);     /* hang up line */
                return;
        }
        lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07);
-       if ((tp->t_local&LLITOUT) || (tp->t_flags&RAW))
+       if (tp->t_flags & (RAW|LITOUT|PASS8))
                lpr |= BITS8;
        else
                lpr |= (BITS7|PENABLE);
                lpr |= BITS8;
        else
                lpr |= (BITS7|PENABLE);
@@ -475,9 +416,8 @@ dzxint(tp)
        register struct tty *tp;
 {
        register struct pdma *dp;
        register struct tty *tp;
 {
        register struct pdma *dp;
-       register s, dz, unit;
+       register dz, unit;
  
  
-       s = spl5();             /* block pdma interrupts */
        dp = (struct pdma *)tp->t_addr;
        tp->t_state &= ~TS_BUSY;
        if (tp->t_state & TS_FLUSH)
        dp = (struct pdma *)tp->t_addr;
        tp->t_state &= ~TS_BUSY;
        if (tp->t_state & TS_FLUSH)
@@ -497,14 +437,13 @@ dzxint(tp)
                        dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit));
                else
                        dp->p_addr->dztcr &= ~(1<<unit);
                        dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit));
                else
                        dp->p_addr->dztcr &= ~(1<<unit);
-       splx(s);
 }
 
 dzstart(tp)
        register struct tty *tp;
 {
        register struct pdma *dp;
 }
 
 dzstart(tp)
        register struct tty *tp;
 {
        register struct pdma *dp;
-       register struct device *dzaddr;
+       register struct dzdevice *dzaddr;
        register int cc;
        int s, dz, unit;
  
        register int cc;
        int s, dz, unit;
  
@@ -526,7 +465,7 @@ dzstart(tp)
        }
        if (tp->t_outq.c_cc == 0)
                goto out;
        }
        if (tp->t_outq.c_cc == 0)
                goto out;
-       if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT))
+       if (tp->t_flags & (RAW|LITOUT))
                cc = ndqb(&tp->t_outq, 0);
        else {
                cc = ndqb(&tp->t_outq, 0200);
                cc = ndqb(&tp->t_outq, 0);
        else {
                cc = ndqb(&tp->t_outq, 0200);
@@ -574,7 +513,7 @@ dzmctl(dev, bits, how)
        dev_t dev;
        int bits, how;
 {
        dev_t dev;
        int bits, how;
 {
-       register struct device *dzaddr;
+       register struct dzdevice *dzaddr;
        register int unit, mbits;
        int b, s;
 
        register int unit, mbits;
        int b, s;
 
@@ -626,13 +565,16 @@ dzmctl(dev, bits, how)
        return(mbits);
 }
  
        return(mbits);
 }
  
+int dztransitions, dzfasttimers;               /*DEBUG*/
 dzscan()
 {
        register i;
 dzscan()
 {
        register i;
-       register struct device *dzaddr;
+       register struct dzdevice *dzaddr;
        register bit;
        register struct tty *tp;
        register car;
        register bit;
        register struct tty *tp;
        register car;
+       int olddzsilos = dzsilos;
+       int dztimer();
  
        for (i = 0; i < dz_cnt ; i++) {
                dzaddr = dzpdma[i].p_addr;
  
        for (i = 0; i < dz_cnt ; i++) {
                dzaddr = dzpdma[i].p_addr;
@@ -651,35 +593,43 @@ dzscan()
                        car = dzaddr->dzmsr&bit;
                if (car) {
                        /* carrier present */
                        car = dzaddr->dzmsr&bit;
                if (car) {
                        /* carrier present */
-                       if ((tp->t_state & TS_CARR_ON) == 0) {
-                               wakeup((caddr_t)&tp->t_rawq);
-                               tp->t_state |= TS_CARR_ON;
-                       }
-               } else {
-                       if ((tp->t_state&TS_CARR_ON) &&
-                           (tp->t_local&LNOHANG)==0) {
-                               /* carrier lost */
-                               if (tp->t_state&TS_ISOPEN) {
-                                       gsignal(tp->t_pgrp, SIGHUP);
-                                       gsignal(tp->t_pgrp, SIGCONT);
-                                       dzaddr->dzdtr &= ~bit;
-                                       flushtty(tp, FREAD|FWRITE);
-                               }
-                               tp->t_state &= ~TS_CARR_ON;
-                       }
+                       if ((tp->t_state & TS_CARR_ON) == 0)
+                               (void)(*linesw[tp->t_line].l_modem)(tp, 1);
+               } else if ((tp->t_state&TS_CARR_ON) &&
+                   (*linesw[tp->t_line].l_modem)(tp, 0) == 0)
+                       dzaddr->dzdtr &= ~bit;
+       }
+       for (i = 0; i < NDZ; i++) {
+               ave(dzrate[i], dzchars[i], 8);
+               if (dzchars[i] > dzhighrate && ((dzsilos & (1 << i)) == 0)) {
+                       dzpdma[i << 3].p_addr->dzcsr = DZ_IEN | DZ_SAE;
+                       dzsilos |= (1 << i);
+                       dztransitions++;                /*DEBUG*/
+               } else if ((dzsilos & (1 << i)) && (dzrate[i] < dzlowrate)) {
+                       dzpdma[i << 3].p_addr->dzcsr = DZ_IEN;
+                       dzsilos &= ~(1 << i);
                }
                }
+               dzchars[i] = 0;
        }
        }
-       timeout(dzscan, (caddr_t)0, 2*hz);
+       if (dzsilos && !olddzsilos)
+               timeout(dztimer, (caddr_t)0, dztimerintvl);
+       timeout(dzscan, (caddr_t)0, hz);
 }
 
 dztimer()
 {
        register int dz;
 }
 
 dztimer()
 {
        register int dz;
-       register int s = spl5();
+       register int s;
 
 
+       if (dzsilos == 0)
+               return;
+       s = spl5();
+       dzfasttimers++;         /*DEBUG*/
        for (dz = 0; dz < NDZ; dz++)
        for (dz = 0; dz < NDZ; dz++)
-               dzrint(dz);
+               if (dzsilos & (1 << dz))
+                   dzrint(dz);
        splx(s);
        splx(s);
+       timeout(dztimer, (caddr_t) 0, dztimerintvl);
 }
 
 /*
 }
 
 /*
@@ -707,6 +657,5 @@ dzreset(uban)
                        dzstart(tp);
                }
        }
                        dzstart(tp);
                }
        }
-       dztimer();
 }
 #endif
 }
 #endif