Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/mscp Copied from ../../arch/vax/mscp/mscp_tape.c, v



details:   https://anonhg.NetBSD.org/src/rev/b58bb95d3281
branches:  trunk
changeset: 473336:b58bb95d3281
user:      ragge <ragge%NetBSD.org@localhost>
date:      Sat May 29 19:12:42 1999 +0000

description:
Copied from ../../arch/vax/mscp/mscp_tape.c,v

diffstat:

 sys/dev/mscp/mscp_tape.c |  566 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 566 insertions(+), 0 deletions(-)

diffs (truncated from 570 to 300 lines):

diff -r 3b558fb29102 -r b58bb95d3281 sys/dev/mscp/mscp_tape.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/mscp/mscp_tape.c  Sat May 29 19:12:42 1999 +0000
@@ -0,0 +1,566 @@
+/*     $NetBSD: mscp_tape.c,v 1.13 1999/05/29 19:12:42 ragge Exp $ */
+/*
+ * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed at Ludd, University of 
+ *     Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/*
+ * MSCP tape device driver
+ */
+
+/*
+ * TODO
+ *     Write status handling code.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/buf.h>
+#include <sys/ioccom.h>
+#include <sys/mtio.h>
+#include <sys/fcntl.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+
+#include <machine/cpu.h>
+
+#include <vax/mscp/mscp.h>
+#include <vax/mscp/mscpvar.h>
+
+#include "locators.h"
+
+/*
+ * Drive status, per drive
+ */
+struct mt_softc {
+       struct  device mt_dev;  /* Autoconf struct */
+       int     mt_state;       /* open/closed state */
+       int     mt_hwunit;      /* Hardware unit number */
+       int     mt_inuse;       /* Locks the tape drive for others */
+       int     mt_waswrite;    /* Last operation was a write op */
+       int     mt_serex;       /* Got serious exception */
+       int     mt_ioctlerr;    /* Error after last ioctl */
+};
+
+#define MT_OFFLINE     0
+#define MT_ONLINE      1
+
+int    mtmatch __P((struct device *, struct cfdata *, void *));
+void   mtattach __P((struct device *, struct device *, void *));
+void   mtdgram __P((struct device *, struct mscp *, struct mscp_softc *));
+void   mtiodone __P((struct device *, struct buf *));
+int    mtonline __P((struct device *, struct mscp *));
+int    mtgotstatus __P((struct device *, struct mscp *));
+int    mtioerror __P((struct device *, struct mscp *, struct buf *));
+void   mtfillin __P((struct buf *, struct mscp *));
+int    mtopen __P((dev_t, int, int, struct proc *));
+int    mtclose __P((dev_t, int, int, struct proc *));
+void   mtstrategy __P((struct buf *));
+int    mtread __P((dev_t, struct uio *));
+int    mtwrite __P((dev_t, struct uio *));
+int    mtioctl __P((dev_t, int, caddr_t, int, struct proc *));
+int    mtdump __P((dev_t, daddr_t, caddr_t, size_t));
+int    mtcmd __P((struct mt_softc *, int, int, int));
+void   mtcmddone __P((struct device *, struct mscp *));
+int    mt_putonline __P((struct mt_softc *));
+
+struct mscp_device mt_device = {
+       mtdgram,
+       mtiodone,
+       mtonline,
+       mtgotstatus,
+       0,
+       mtioerror,
+       0,
+       mtfillin,
+       mtcmddone,
+};
+
+/* This is not good, should allow more than 4 tapes/device type */
+#define mtunit(dev)    (minor(dev) & T_UNIT)
+#define mtnorewind(dev) (dev & T_NOREWIND)
+#define mthdensity(dev) (dev & T_1600BPI)
+
+struct cfattach mt_ca = {
+       sizeof(struct mt_softc), mtmatch, mtattach
+};
+
+extern struct cfdriver mt_cd;
+
+/*
+ * More driver definitions, for generic MSCP code.
+ */
+
+int
+mtmatch(parent, cf, aux)
+       struct  device *parent;
+       struct  cfdata *cf;
+       void    *aux;
+{
+       struct  drive_attach_args *da = aux;
+       struct  mscp *mp = da->da_mp;
+
+       if ((da->da_typ & MSCPBUS_TAPE) == 0)
+               return 0;
+       if (cf->cf_loc[MSCPBUSCF_DRIVE] != MSCPBUSCF_DRIVE_DEFAULT &&
+           cf->cf_loc[MSCPBUSCF_DRIVE] != mp->mscp_unit)
+               return 0;
+       return 1;
+}
+
+/*
+ * The attach routine only checks and prints drive type.
+ */
+void
+mtattach(parent, self, aux)
+       struct  device *parent, *self;
+       void    *aux; 
+{
+       struct  mt_softc *mt = (void *)self;
+       struct  drive_attach_args *da = aux;
+       struct  mscp *mp = da->da_mp;
+       struct  mscp_softc *mi = (void *)parent;
+
+       mt->mt_hwunit = mp->mscp_unit;
+       mi->mi_dp[mp->mscp_unit] = self;
+
+       disk_printtype(mp->mscp_unit, mp->mscp_guse.guse_mediaid);
+}
+
+/* 
+ * (Try to) put the drive online. This is done the first time the
+ * drive is opened, or if it has fallen offline.
+ */
+int
+mt_putonline(mt)
+       struct mt_softc *mt;
+{
+       struct  mscp *mp;
+       struct  mscp_softc *mi = (struct mscp_softc *)mt->mt_dev.dv_parent;
+       volatile int i;
+
+       (volatile int)mt->mt_state = MT_OFFLINE;
+       mp = mscp_getcp(mi, MSCP_WAIT);
+       mp->mscp_opcode = M_OP_ONLINE;
+       mp->mscp_unit = mt->mt_hwunit;
+       mp->mscp_cmdref = (long)&mt->mt_state;
+       *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
+
+       /* Poll away */
+       i = *mi->mi_ip;
+       if (tsleep(&mt->mt_state, PRIBIO, "mtonline", 240 * hz))
+               return MSCP_FAILED;
+
+       if ((volatile int)mt->mt_state != MT_ONLINE)
+               return MSCP_FAILED;
+
+       return MSCP_DONE;
+}
+/*
+ * Open a drive.
+ */
+/*ARGSUSED*/
+int
+mtopen(dev, flag, fmt, p)
+       dev_t dev;
+       int flag, fmt;
+       struct  proc *p;
+{
+       register struct mt_softc *mt;
+       int unit;
+
+       /*
+        * Make sure this is a reasonable open request.
+        */
+       unit = mtunit(dev);
+       if (unit >= mt_cd.cd_ndevs)
+               return ENXIO;
+       mt = mt_cd.cd_devs[unit];
+       if (mt == 0)
+               return ENXIO;
+
+       if (mt->mt_inuse)
+                       return EBUSY;
+       mt->mt_inuse = 1;
+
+       if (mt_putonline(mt) == MSCP_FAILED) {
+               mt->mt_inuse = 0;
+               return EIO;
+       }
+
+       return 0;
+}
+
+/* ARGSUSED */
+int
+mtclose(dev, flags, fmt, p)
+       dev_t dev;
+       int flags, fmt;
+       struct  proc *p;
+{
+       int unit = mtunit(dev);
+       struct mt_softc *mt = mt_cd.cd_devs[unit];
+
+       /*
+        * If we just have finished a writing, write EOT marks.
+        */
+       if ((flags & FWRITE) && mt->mt_waswrite) {
+               mtcmd(mt, MTWEOF, 0, 0);
+               mtcmd(mt, MTWEOF, 0, 0);
+               mtcmd(mt, MTBSR, 1, 0);
+       }
+       if (mtnorewind(dev) == 0)
+               mtcmd(mt, MTREW, 0, 1);
+       if (mt->mt_serex)
+               mtcmd(mt, -1, 0, 0);
+
+       mt->mt_inuse = 0; /* Release the tape */
+       return 0;
+}
+
+void
+mtstrategy(bp)
+       register struct buf *bp;
+{
+       register int unit;
+       register struct mt_softc *mt;
+
+       /*
+        * Make sure this is a reasonable drive to use.
+        */
+       unit = mtunit(bp->b_dev);
+       if (unit > mt_cd.cd_ndevs || (mt = mt_cd.cd_devs[unit]) == NULL) {
+               bp->b_error = ENXIO;
+               goto bad;
+       }
+
+       mt->mt_waswrite = bp->b_flags & B_READ ? 0 : 1;
+       mscp_strategy(bp, mt->mt_dev.dv_parent);
+       return;
+
+bad:
+       bp->b_flags |= B_ERROR;
+       biodone(bp);
+}
+
+int
+mtread(dev, uio)
+       dev_t dev;
+       struct uio *uio;
+{
+
+       return (physio(mtstrategy, NULL, dev, B_READ, minphys, uio));
+}
+
+int
+mtwrite(dev, uio)
+       dev_t dev;
+       struct uio *uio;
+{
+
+       return (physio(mtstrategy, NULL, dev, B_WRITE, minphys, uio));
+}
+
+void
+mtiodone(usc, bp)
+       struct device *usc;
+       struct buf *bp;



Home | Main Index | Thread Index | Old Index