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