Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/qbus Add the famous "rl" disk.



details:   https://anonhg.NetBSD.org/src/rev/dc02ccd40b82
branches:  trunk
changeset: 485226:dc02ccd40b82
user:      ragge <ragge%NetBSD.org@localhost>
date:      Sat Apr 22 16:46:45 2000 +0000

description:
Add the famous "rl" disk.

diffstat:

 sys/dev/qbus/files.uba |    9 +-
 sys/dev/qbus/rl.c      |  570 +++++++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/qbus/rlreg.h   |   92 +++++++
 3 files changed, 670 insertions(+), 1 deletions(-)

diffs (truncated from 690 to 300 lines):

diff -r 4118f3980d9c -r dc02ccd40b82 sys/dev/qbus/files.uba
--- a/sys/dev/qbus/files.uba    Sat Apr 22 16:43:47 2000 +0000
+++ b/sys/dev/qbus/files.uba    Sat Apr 22 16:46:45 2000 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.uba,v 1.6 1999/06/20 18:09:22 ragge Exp $
+#      $NetBSD: files.uba,v 1.7 2000/04/22 16:46:45 ragge Exp $
 #
 # Config file and device description for machine-independent
 # code for devices Digital Equipment Corp. Unibus and Q22 bus.
@@ -49,3 +49,10 @@
 
 # Fontfile for DEC framebuffers, soon to die in favour for MI fontfiles.
 file   dev/qbus/qfont.c                        qfont
+
+# RL01/02 disk controller
+device rlc { drive=-1 }
+attach rlc at uba
+device rl: disk
+attach rl at rlc
+file   dev/qbus/rl.c                           rl | rlc needs-flag
diff -r 4118f3980d9c -r dc02ccd40b82 sys/dev/qbus/rl.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/qbus/rl.c Sat Apr 22 16:46:45 2000 +0000
@@ -0,0 +1,570 @@
+/*     $NetBSD: rl.c,v 1.1 2000/04/22 16:46:46 ragge Exp $     */
+
+/*
+ * Copyright (c) 2000 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.
+ */
+
+/*
+ * RL11/RLV11/RLV12 disk controller driver and
+ * RL01/RL02 disk device driver.
+ *
+ * TODO:
+ *     Handle disk errors more gracefully
+ *     Do overlapping seeks on multiple drives
+ *
+ * Implementation comments:
+ *     
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/disk.h>
+#include <sys/disklabel.h>
+#include <sys/buf.h>
+#include <sys/stat.h>
+#include <sys/dkio.h>
+#include <sys/fcntl.h>
+
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
+
+#include <machine/bus.h>
+
+#include <dev/qbus/ubavar.h>
+#include <dev/qbus/rlreg.h>
+
+#include "ioconf.h"
+#include "locators.h"
+
+struct rlc_softc {
+       struct device sc_dev;
+       bus_space_tag_t sc_iot;
+       bus_space_handle_t sc_ioh;
+       bus_dma_tag_t sc_dmat;
+       bus_dmamap_t sc_dmam;
+       struct buf_queue sc_q;          /* Queue of waiting bufs */
+       struct buf *sc_active;          /* Currently active buf */
+       caddr_t sc_bufaddr;             /* Current in-core address */
+       int sc_diskblk;                 /* Current block on disk */
+       int sc_bytecnt;                 /* How much left to transfer */
+};
+
+struct rl_softc {
+       struct device rc_dev;
+       struct disk rc_disk;
+       int rc_state;
+       int rc_head;
+       int rc_cyl;
+       int rc_hwid;
+};
+
+static int rlcmatch(struct device *, struct cfdata *, void *);
+static void rlcattach(struct device *, struct device *, void *);
+static int rlcprint(void *, const char *);
+static void rlcintr(void *);
+static int rlmatch(struct device *, struct cfdata *, void *);
+static void rlattach(struct device *, struct device *, void *);
+static void rlcstart(struct rlc_softc *, struct buf *);
+static void waitcrdy(struct rlc_softc *);
+cdev_decl(rl);
+bdev_decl(rl);
+
+struct cfattach rlc_ca = {
+       sizeof(struct rlc_softc), rlcmatch, rlcattach
+};
+
+struct cfattach rl_ca = {
+       sizeof(struct rl_softc), rlmatch, rlattach
+};
+
+struct rlc_attach_args {
+       u_int16_t type;
+       int hwid;
+};
+
+#define        MAXRLXFER (RL_BPS * RL_SPT)
+#define        RLMAJOR 14
+
+#define        RL_WREG(reg, val) \
+       bus_space_write_2(sc->sc_iot, sc->sc_ioh, (reg), (val))
+#define RL_RREG(reg) \
+       bus_space_read_2(sc->sc_iot, sc->sc_ioh, (reg))
+
+void
+waitcrdy(struct rlc_softc *sc)
+{
+       int i;
+
+       for (i = 0; i < 1000; i++) {
+               DELAY(10000);
+               if (RL_RREG(RL_CS) & RLCS_CRDY)
+                       return;
+       }
+       printf("%s: never got ready\n", sc->sc_dev.dv_xname); /* ?panic? */
+}
+
+int
+rlcprint(void *aux, const char *name)
+{
+       struct rlc_attach_args *ra = aux;
+
+       if (name)
+               printf("RL0%d at %s", ra->type & RLMP_DT ? '2' : '1', name);
+       printf(" drive %d", ra->hwid);
+       return UNCONF;
+}
+
+/*
+ * Force the controller to interrupt.
+ */
+int
+rlcmatch(struct device *parent, struct cfdata *cf, void *aux)
+{
+       struct uba_attach_args *ua = aux;
+       struct rlc_softc ssc, *sc = &ssc;
+       int i;
+
+       sc->sc_iot = ua->ua_iot;
+       sc->sc_ioh = ua->ua_ioh;
+       /* Force interrupt by issuing a "Get Status" command */
+       RL_WREG(RL_DA, RLDA_GS);
+       RL_WREG(RL_CS, RLCS_GS|RLCS_IE);
+
+       for (i = 0; i < 100; i++) {
+               DELAY(100000);
+               if (RL_RREG(RL_CS) & RLCS_CRDY)
+                       return 1;
+       }
+       return 0;
+}
+
+void
+rlcattach(struct device *parent, struct device *self, void *aux)
+{
+       struct rlc_softc *sc = (struct rlc_softc *)self;
+       struct uba_attach_args *ua = aux;
+       struct rlc_attach_args ra;
+       int i, error;
+
+       sc->sc_iot = ua->ua_iot;
+       sc->sc_ioh = ua->ua_ioh;
+       sc->sc_dmat = ua->ua_dmat;
+       uba_intr_establish(ua->ua_icookie, ua->ua_cvec, rlcintr, sc);
+       printf("\n");
+
+       /*
+        * The RL11 can only have one transfer going at a time, 
+        * and max transfer size is one track, so only one dmamap
+        * is needed.
+        */
+       error = bus_dmamap_create(sc->sc_dmat, MAXRLXFER, 1, MAXRLXFER, 0,
+           BUS_DMA_ALLOCNOW, &sc->sc_dmam);
+       if (error) {
+               printf(": Failed to allocate DMA map, error %d\n", error);
+               return;
+       }
+       BUFQ_INIT(&sc->sc_q);
+       for (i = 0; i < RL_MAXDPC; i++) {
+               waitcrdy(sc);
+               RL_WREG(RL_DA, RLDA_GS|RLDA_RST);
+               RL_WREG(RL_CS, RLCS_GS|(i << RLCS_USHFT));
+               waitcrdy(sc);
+               ra.type = RL_RREG(RL_MP);
+               ra.hwid = i;
+               if ((RL_RREG(RL_CS) & RLCS_ERR) == 0)
+                       config_found(&sc->sc_dev, &ra, rlcprint);
+       }
+}
+
+int
+rlmatch(struct device *parent, struct cfdata *cf, void *aux)
+{
+       struct rlc_attach_args *ra = aux;
+
+       if (cf->cf_loc[RLCCF_DRIVE] != RLCCF_DRIVE_DEFAULT &&
+           cf->cf_loc[RLCCF_DRIVE] != ra->hwid)
+               return 0;
+       return 1;
+}
+
+void
+rlattach(struct device *parent, struct device *self, void *aux)
+{
+       struct rl_softc *rc = (struct rl_softc *)self;
+       struct rlc_attach_args *ra = aux;
+       struct disklabel *dl;
+
+       rc->rc_hwid = ra->hwid;
+       rc->rc_disk.dk_name = rc->rc_dev.dv_xname;
+       disk_attach(&rc->rc_disk);
+       dl = rc->rc_disk.dk_label;
+       dl->d_npartitions = 3;
+       strcpy(dl->d_typename, "RL01");
+       if (ra->type & RLMP_DT)
+               dl->d_typename[3] = '2';
+       dl->d_secsize = DEV_BSIZE; /* XXX - wrong, but OK for now */
+       dl->d_nsectors = RL_SPT/2;
+       dl->d_ntracks = RL_SPD;
+       dl->d_ncylinders = ra->type & RLMP_DT ? RL_TPS02 : RL_TPS01;
+       dl->d_secpercyl = dl->d_nsectors * dl->d_ntracks;
+       dl->d_secperunit = dl->d_ncylinders * dl->d_secpercyl;
+       dl->d_partitions[0].p_size = dl->d_partitions[2].p_size =
+           dl->d_secperunit;
+       dl->d_partitions[0].p_offset = dl->d_partitions[2].p_offset = 0;
+       dl->d_interleave = dl->d_headswitch = 1;
+       dl->d_bbsize = BBSIZE;
+       dl->d_sbsize = SBSIZE;
+       dl->d_rpm = 2400;
+       dl->d_type = DTYPE_DEC;
+       printf(": %s\n", dl->d_typename);
+}
+
+int
+rlopen(dev_t dev, int flag, int fmt, struct proc *p)
+{
+       int part, unit, mask;
+       struct disklabel *dl;
+       struct rlc_softc *sc;
+       struct rl_softc *rc;
+       char *msg;
+       /*
+        * Make sure this is a reasonable open request.
+        */
+       unit = DISKUNIT(dev);
+       if (unit >= rl_cd.cd_ndevs)
+               return ENXIO;
+       rc = rl_cd.cd_devs[unit];
+       if (rc == 0)
+               return ENXIO;
+
+       sc = (struct rlc_softc *)rc->rc_dev.dv_parent;
+       /* XXX - check that the disk actually is useable */
+       /*
+        * If this is the first open; read in where on the disk we are.
+        */
+       dl = rc->rc_disk.dk_label;
+       if (rc->rc_state == DK_CLOSED) {
+               u_int16_t mp;
+               RL_WREG(RL_CS, RLCS_RHDR|(rc->rc_hwid << RLCS_USHFT));



Home | Main Index | Thread Index | Old Index