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