Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/qbus Copied from ../../arch/vax/uba/uda.c,v
details: https://anonhg.NetBSD.org/src/rev/136ae536bf59
branches: trunk
changeset: 473324:136ae536bf59
user: ragge <ragge%NetBSD.org@localhost>
date: Sat May 29 17:03:17 1999 +0000
description:
Copied from ../../arch/vax/uba/uda.c,v
diffstat:
sys/dev/qbus/uda.c | 520 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 520 insertions(+), 0 deletions(-)
diffs (truncated from 524 to 300 lines):
diff -r 7e7b64f76422 -r 136ae536bf59 sys/dev/qbus/uda.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/qbus/uda.c Sat May 29 17:03:17 1999 +0000
@@ -0,0 +1,520 @@
+/* $NetBSD: uda.c,v 1.29 1999/05/29 17:03:17 ragge Exp $ */
+/*
+ * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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 by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ * @(#)uda.c 7.32 (Berkeley) 2/13/91
+ */
+
+/*
+ * UDA50 disk device driver
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#include <machine/sid.h>
+#include <machine/pte.h>
+#include <machine/cpu.h>
+
+#include <vax/uba/ubareg.h>
+#include <vax/uba/ubavar.h>
+#include <vax/uba/udareg.h>
+
+#include <vax/mscp/mscp.h>
+#include <vax/mscp/mscpvar.h>
+#include <vax/mscp/mscpreg.h>
+
+/*
+ * Variants of SIMPLEQ macros for use with buf structs.
+ */
+#define BUFQ_INSERT_TAIL(head, elm) { \
+ (elm)->b_actf = NULL; \
+ *(head)->sqh_last = (elm); \
+ (head)->sqh_last = &(elm)->b_actf; \
+}
+
+#define BUFQ_REMOVE_HEAD(head, elm) { \
+ if (((head)->sqh_first = (elm)->b_actf) == NULL) \
+ (head)->sqh_last = &(head)->sqh_first; \
+}
+
+/*
+ * Software status, per controller.
+ */
+struct uda_softc {
+ struct device sc_dev; /* Autoconfig info */
+ struct uba_unit sc_unit; /* Struct common for UBA to communicate */
+ SIMPLEQ_HEAD(, buf) sc_bufq; /* bufs awaiting for resources */
+ struct mscp_pack *sc_uuda; /* Unibus address of uda struct */
+ struct mscp_pack sc_uda; /* Struct for uda communication */
+ struct udadevice *sc_udadev; /* pointer to ip/sa regs */
+ struct mscp *sc_mscp; /* Keep pointer to active mscp */
+ short sc_ipl; /* interrupt priority, Q-bus */
+ struct mscp_softc *sc_softc; /* MSCP info (per mscpvar.h) */
+ int sc_wticks; /* watchdog timer ticks */
+};
+
+static int udamatch __P((struct device *, struct cfdata *, void *));
+static void udaattach __P((struct device *, struct device *, void *));
+static void udareset __P((int));
+static void mtcreset __P((int));
+static void reset __P((struct uda_softc *));
+static void udaintr __P((int));
+static void mtcintr __P((int));
+static void intr __P((struct uda_softc *));
+int udaready __P((struct uba_unit *));
+void udactlrdone __P((struct device *, int));
+int udaprint __P((void *, const char *));
+void udasaerror __P((struct device *, int));
+int udago __P((struct device *, struct buf *));
+
+extern struct cfdriver mtc_cd;
+
+struct cfattach mtc_ca = {
+ sizeof(struct uda_softc), udamatch, udaattach
+};
+
+extern struct cfdriver uda_cd;
+
+struct cfattach uda_ca = {
+ sizeof(struct uda_softc), udamatch, udaattach
+};
+
+/*
+ * More driver definitions, for generic MSCP code.
+ */
+struct mscp_ctlr uda_mscp_ctlr = {
+ udactlrdone,
+ udago,
+ udasaerror,
+};
+
+/*
+ * Miscellaneous private variables.
+ */
+static int ivec_no;
+
+int
+udaprint(aux, name)
+ void *aux;
+ const char *name;
+{
+ if (name)
+ printf("%s: mscpbus", name);
+ return UNCONF;
+}
+
+/*
+ * Poke at a supposed UDA50 to see if it is there.
+ */
+int
+udamatch(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct uba_attach_args *ua = aux;
+ struct mscp_softc mi; /* Nice hack */
+ struct uba_softc *ubasc;
+ int tries;
+#if QBA && notyet
+ extern volatile int rbr;
+ int s;
+#endif
+
+ /* Get an interrupt vector. */
+ ubasc = (void *)parent;
+ ivec_no = ubasc->uh_lastiv - 4;
+
+ mi.mi_sa = &((struct udadevice *)ua->ua_addr)->udasa;
+ mi.mi_ip = &((struct udadevice *)ua->ua_addr)->udaip;
+
+ /*
+ * Initialise the controller (partially). The UDA50 programmer's
+ * manual states that if initialisation fails, it should be retried
+ * at least once, but after a second failure the port should be
+ * considered `down'; it also mentions that the controller should
+ * initialise within ten seconds. Or so I hear; I have not seen
+ * this manual myself.
+ */
+#if 0
+ s = spl6();
+#endif
+ tries = 0;
+again:
+
+ *mi.mi_ip = 0;
+ if (mscp_waitstep(&mi, MP_STEP1, MP_STEP1) == 0)
+ return 0; /* Nothing here... */
+
+ *mi.mi_sa = MP_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) | MP_IE |
+ (ivec_no >> 2);
+
+ if (mscp_waitstep(&mi, MP_STEP2, MP_STEP2) == 0) {
+ printf("udaprobe: init step2 no change. sa=%x\n", *mi.mi_sa);
+ goto bad;
+ }
+
+ /* should have interrupted by now */
+#if 0
+ rbr = qbgetpri();
+#endif
+ if (strcmp(cf->cf_driver->cd_name, mtc_cd.cd_name)) {
+ ua->ua_ivec = udaintr;
+ ua->ua_reset = udareset;
+ } else {
+ ua->ua_ivec = mtcintr;
+ ua->ua_reset = mtcreset;
+ }
+
+ return 1;
+bad:
+ if (++tries < 2)
+ goto again;
+#if 0
+ splx(s);
+#endif
+ return 0;
+}
+
+void
+udaattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct uda_softc *sc = (void *)self;
+ struct uba_attach_args *ua = aux;
+ struct uba_softc *uh = (void *)parent;
+ struct mscp_attach_args ma;
+ int ctlr, ubinfo;
+
+ printf("\n");
+
+ uh->uh_lastiv -= 4; /* remove dynamic interrupt vector */
+#ifdef QBA
+ sc->sc_ipl = ua->ua_br;
+#endif
+
+ ctlr = sc->sc_dev.dv_unit;
+ sc->sc_udadev = (struct udadevice *)ua->ua_addr;
+ SIMPLEQ_INIT(&sc->sc_bufq);
+
+ /*
+ * Fill in the uba_unit struct, so we can communicate with the uba.
+ */
+ sc->sc_unit.uu_softc = sc; /* Backpointer to softc */
+ sc->sc_unit.uu_ready = udaready;/* go routine called from adapter */
+ sc->sc_unit.uu_keepbdp = vax_cputype == VAX_750 ? 1 : 0;
+
+ /*
+ * Map the communication area and command and
+ * response packets into Unibus space.
+ */
+ ubinfo = uballoc((struct uba_softc *)sc->sc_dev.dv_parent,
+ (caddr_t) &sc->sc_uda, sizeof (struct mscp_pack), UBA_CANTWAIT);
+
+#ifdef DIAGNOSTIC
+ if (ubinfo == 0) {
+ printf("%s: uballoc map failed\n", sc->sc_dev.dv_xname);
+ return;
+ }
+#endif
+ sc->sc_uuda = (struct mscp_pack *) UBAI_ADDR(ubinfo);
+
+ bzero(&sc->sc_uda, sizeof (struct mscp_pack));
+
+ /*
+ * The only thing that differ UDA's and Tape ctlr's is
+ * their vcid. Beacuse there are no way to determine which
+ * ctlr type it is, we check what is generated and later
+ * set the correct vcid.
+ */
+ ma.ma_type = (strcmp(self->dv_cfdata->cf_driver->cd_name,
+ mtc_cd.cd_name) ? MSCPBUS_DISK : MSCPBUS_TAPE);
+
+ ma.ma_mc = &uda_mscp_ctlr;
+ ma.ma_type |= MSCPBUS_UDA;
+ ma.ma_uuda = sc->sc_uuda;
+ ma.ma_uda = &sc->sc_uda;
+ ma.ma_softc = &sc->sc_softc;
+ ma.ma_ip = &sc->sc_udadev->udaip;
+ ma.ma_sa = ma.ma_sw = &sc->sc_udadev->udasa;
+ ma.ma_ivec = ivec_no;
+ ma.ma_ctlrnr = (ua->ua_iaddr == 0172150 ? 0 : 1); /* XXX */
+ ma.ma_adapnr = uh->uh_nr;
+ config_found(&sc->sc_dev, &ma, udaprint);
+}
+
+/*
+ * Start a transfer if there are free resources available, otherwise
+ * let it go in udaready, forget it for now.
+ */
+int
+udago(usc, bp)
+ struct device *usc;
+ struct buf *bp;
+{
+ struct uda_softc *sc = (void *)usc;
+ struct uba_unit *uu = &sc->sc_unit;
+
+ /*
+ * If we already are queued for resources, don't call ubaqueue
+ * again. (Then we would trash the wait queue). Just queue the
Home |
Main Index |
Thread Index |
Old Index