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