Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/vax/vax Add checksum calculation, busy-wait loops f...



details:   https://anonhg.NetBSD.org/src/rev/b2b61ebf488f
branches:  trunk
changeset: 509824:b2b61ebf488f
user:      ragge <ragge%NetBSD.org@localhost>
date:      Sun May 13 21:19:44 2001 +0000

description:
Add checksum calculation, busy-wait loops for receive packets and use
correct interrupt levels (spl7). Reading tapes now work reliable.

diffstat:

 sys/arch/vax/vax/ctu.c |  496 +++++++++++++++++++++++++++---------------------
 1 files changed, 276 insertions(+), 220 deletions(-)

diffs (truncated from 643 to 300 lines):

diff -r a239c6a3fdf6 -r b2b61ebf488f sys/arch/vax/vax/ctu.c
--- a/sys/arch/vax/vax/ctu.c    Sun May 13 20:54:42 2001 +0000
+++ b/sys/arch/vax/vax/ctu.c    Sun May 13 21:19:44 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ctu.c,v 1.12 2001/04/12 06:20:59 thorpej Exp $ */
+/*     $NetBSD: ctu.c,v 1.13 2001/05/13 21:19:44 ragge Exp $ */
 /*
  * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
  * All rights reserved.
@@ -33,8 +33,6 @@
 /*
  * Device driver for 11/750 Console TU58.
  *
- * Error checking is almost nonexistent, the driver should be
- * fixed to at least calculate checksum on incoming packets.
  * Writing of tapes does not work, by some unknown reason so far.
  * It is almost useless to try to use this driver when running
  * multiuser, because the serial device don't have any buffers 
@@ -51,60 +49,52 @@
 #include <sys/ioctl.h>
 #include <sys/device.h>
 #include <sys/proc.h>
-#include <sys/disklabel.h>     /* For disklabel prototype */
+#include <sys/conf.h>
 
 #include <machine/mtpr.h>
 #include <machine/rsp.h>
 #include <machine/scb.h>
 #include <machine/trap.h>
 
-enum tu_state {
-       SC_UNUSED,
-       SC_INIT,
-       SC_READY,
-       SC_SEND_CMD,
-       SC_GET_RESP,
-       SC_GET_WCONT,
-       SC_GET_END,
-       SC_RESTART,
-};
+#undef TUDEBUG
+
+#define        TU_IDLE         0
+#define        TU_RESET        1
+#define        TU_RUNNING      2
+#define        TU_WORKING      3
+#define TU_READING     4
+#define TU_WRITING     5
+#define        TU_ENDPACKET    6
+#define        TU_RESTART      7
 
 struct tu_softc {
-       enum    tu_state sc_state;
-       int     sc_error;
+       int     sc_state;
+       int     sc_step;
        char    sc_rsp[15];     /* Should be struct rsb; but don't work */
-       u_char  *sc_xfptr;      /* Current char to xfer */
-       u_char  *sc_blk;        /* Base of current 128b block */
        int     sc_tpblk;       /* Start block number */
-       int     sc_nbytes;      /* Number of bytes to xfer */
+       int     sc_wto;         /* Timeout counter */
        int     sc_xbytes;      /* Number of xfer'd bytes */
-       int     sc_bbytes;      /* Number of xfer'd bytes this block */
        int     sc_op;          /* Read/write */
-       int     sc_xmtok;       /* set if OK to xmit */
-       struct  buf_queue sc_q; /* pending I/O requests */
+       struct  buf_queue sc_bufq;      /* pending I/O requests */
 } tu_sc;
 
 struct ivec_dsp tu_recv, tu_xmit;
 
-void   ctutintr __P((void *));
-void   cturintr __P((void *));
-void   ctuattach __P((void));
-void   ctustart __P((struct buf *));
-void   ctuwatch __P((void *));
-short  ctu_cksum __P((unsigned short *, int));
+       void ctuattach(void);
+static void ctutintr(void *);
+static void cturintr(void *);
+static void ctustart(void);
+static void ctuwatch(void *);
+static u_short ctu_cksum(unsigned short *, int);
 
-int    ctuopen __P((dev_t, int, int, struct proc *));
-int    ctuclose __P((dev_t, int, int, struct proc *));
-void   ctustrategy __P((struct buf *));
-int    ctuioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-int    ctudump __P((dev_t, daddr_t, caddr_t, size_t));
+bdev_decl(ctu);
 
 static struct callout ctu_watch_ch = CALLOUT_INITIALIZER;
 
 void
 ctuattach()
 {
-       BUFQ_INIT(&tu_sc.sc_q);
+       BUFQ_INIT(&tu_sc.sc_bufq);
 
        tu_recv = idsptch;
        tu_recv.hoppaddr = cturintr;
@@ -115,94 +105,109 @@
        scb->scb_cstint = (void *)&tu_xmit;
 }
 
-int
-ctuopen(dev, oflags, devtype, p)
-       dev_t dev;
-       int oflags, devtype;
-       struct proc *p;
+static void
+ctuinit(void)
 {
-       int unit, error;
+       int s = spl7();
+#define        WAIT    while ((mfpr(PR_CSTS) & 0x80) == 0)
 
-       unit = minor(dev);
+       /*
+        * Do a reset as described in the
+        * "TU58 DECtape II Users Guide".
+        */
+       mtpr(0101, PR_CSTS);    /* Enable transmit interrupt + send break */
+       WAIT;
+       mtpr(0, PR_CSTD); WAIT;
+       mtpr(0, PR_CSTD); WAIT;
+       mtpr(RSP_TYP_INIT, PR_CSTD); WAIT;
+       mtpr(RSP_TYP_INIT, PR_CSTD); WAIT;
+#undef WAIT
+       splx(s);
+}
 
-       if (unit)
+int
+ctuopen(dev_t dev, int oflags, int devtype, struct proc *p)
+{
+       int error;
+
+       if (minor(dev))
                return ENXIO;
 
-       if (tu_sc.sc_state != SC_UNUSED)
+       if (tu_sc.sc_state != TU_IDLE)
                return EBUSY;
 
-       tu_sc.sc_error = 0;
+       tu_sc.sc_state = TU_RESET;
+       tu_sc.sc_step = 0;
        mtpr(0100, PR_CSRS);    /* Enable receive interrupt */
+       mtpr(0101, PR_CSTS);    /* Enable transmit interrupt + send break */
+       if ((error = tsleep((caddr_t)&tu_sc, (PZERO + 10)|PCATCH, "reset", 0)))
+               return error;
+       
+#ifdef TUDEBUG
+       printf("ctuopen: running\n");
+#endif
+       tu_sc.sc_state = TU_RUNNING;
        callout_reset(&ctu_watch_ch, hz, ctuwatch, NULL);
-
-       tu_sc.sc_state = SC_INIT;
-
-       mtpr(RSP_TYP_INIT, PR_CSTD);
-
-        if ((error = tsleep((caddr_t)&tu_sc, (PZERO + 10)|PCATCH,
-           "ctuopen", 0)))
-                return (error);
-
-       if (tu_sc.sc_error)
-               return tu_sc.sc_error;
-
-       tu_sc.sc_state = SC_READY;
-       tu_sc.sc_xmtok = 1;
-
-       mtpr(0100, PR_CSTS);
        return 0;
 
 }
 
 int
-ctuclose(dev, oflags, devtype, p)
-       dev_t dev;
-       int oflags, devtype;
-       struct proc *p;
+ctuclose(dev_t dev, int oflags, int devtype, struct proc *p)
 {
+       struct buf *bp;
+       int s = spl7();
+       while ((bp = BUFQ_FIRST(&tu_sc.sc_bufq)))
+               BUFQ_REMOVE(&tu_sc.sc_bufq, bp);
+       splx(s);
+
        mtpr(0, PR_CSRS);
        mtpr(0, PR_CSTS);
-       tu_sc.sc_state = SC_UNUSED;
+       tu_sc.sc_state = TU_IDLE;
        callout_stop(&ctu_watch_ch);
        return 0;
 }
 
 void
-ctustrategy(bp)
-       struct buf *bp;
+ctustrategy(struct buf *bp)
 {
-       int     s;
+       int s, empty;
 
 #ifdef TUDEBUG
-       printf("addr %x, block %x, nblock %x, read %x\n",
-               bp->b_data, bp->b_blkno, bp->b_bcount,
-               bp->b_flags & B_READ);
+       printf("ctustrategy: bcount %ld blkno %d\n", bp->b_bcount, bp->b_blkno);
+       printf("ctustrategy: bp %p\n", bp);
 #endif
-
        if (bp->b_blkno >= 512) {
-               biodone(bp);
-               return;
+               bp->b_resid = bp->b_bcount;
+               return biodone(bp);
        }
-       bp->b_rawblkno = bp->b_blkno;
-       s = splbio();
-       disksort_blkno(&tu_sc.sc_q, bp); /* Why not use disksort? */
-       if (tu_sc.sc_state == SC_READY)
-               ctustart(bp);
+
+       s = spl7();
+       empty = TAILQ_EMPTY(&tu_sc.sc_bufq.bq_head);
+       BUFQ_INSERT_TAIL(&tu_sc.sc_bufq, bp);
+       if (empty)
+               ctustart();
        splx(s);
 }
 
 void
-ctustart(bp)
-       struct  buf *bp;
+ctustart()
 {
        struct rsp *rsp = (struct rsp *)tu_sc.sc_rsp;
-
+       struct buf *bp;
 
-       tu_sc.sc_xfptr = tu_sc.sc_blk = bp->b_data;
+       bp = BUFQ_FIRST(&tu_sc.sc_bufq);
+       if (bp == NULL)
+               return;
+#ifdef TUDEBUG
+       printf("ctustart\n");
+#endif
        tu_sc.sc_tpblk = bp->b_blkno;
-       tu_sc.sc_nbytes = bp->b_bcount;
-       tu_sc.sc_xbytes = tu_sc.sc_bbytes = 0;
+       tu_sc.sc_xbytes = 0;
        tu_sc.sc_op = bp->b_flags & B_READ ? RSP_OP_READ : RSP_OP_WRITE;
+       tu_sc.sc_step = 0;
+       bp->b_resid = bp->b_bcount;
+       tu_sc.sc_wto = 0;
 
        rsp->rsp_typ = RSP_TYP_COMMAND;
        rsp->rsp_sz = 012;
@@ -210,173 +215,208 @@
        rsp->rsp_mod = 0;
        rsp->rsp_drv = 0;
        rsp->rsp_sw = rsp->rsp_xx1 = rsp->rsp_xx2 = 0;
-       rsp->rsp_cnt = tu_sc.sc_nbytes;
+       rsp->rsp_cnt = bp->b_bcount;
        rsp->rsp_blk = tu_sc.sc_tpblk;
        rsp->rsp_sum = ctu_cksum((unsigned short *)rsp, 6);
-       tu_sc.sc_state = SC_SEND_CMD;
-       if (tu_sc.sc_xmtok) {
-               tu_sc.sc_xmtok = 0;
-               ctutintr(NULL);
-       }
+       tu_sc.sc_state = TU_WORKING;
+       ctutintr(NULL);
 }
 
 int
-ctuioctl(dev, cmd, data, fflag, p)
-       dev_t dev;
-       u_long cmd;
-       caddr_t data;
-       int fflag;
-       struct proc *p;
+ctuioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p)
 {
-       return 0;
+       return ENOTTY;
 }
 
 /*
  * Not bloody likely... 
  */
 int
-ctudump(dev, blkno, va, size)
-       dev_t dev;
-       daddr_t blkno;



Home | Main Index | Thread Index | Old Index