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_subr.c, v



details:   https://anonhg.NetBSD.org/src/rev/3b558fb29102
branches:  trunk
changeset: 473335:3b558fb29102
user:      ragge <ragge%NetBSD.org@localhost>
date:      Sat May 29 19:11:52 1999 +0000

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

diffstat:

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

diffs (truncated from 848 to 300 lines):

diff -r 95a6b71db962 -r 3b558fb29102 sys/dev/mscp/mscp_subr.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/mscp/mscp_subr.c  Sat May 29 19:11:52 1999 +0000
@@ -0,0 +1,844 @@
+/*     $NetBSD: mscp_subr.c,v 1.11 1999/05/29 19:11:52 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.
+ *
+ *     @(#)mscp.c      7.5 (Berkeley) 12/16/90
+ */
+
+/*
+ * MSCP generic driver routines
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/buf.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+
+#include <machine/sid.h>
+
+#include <vax/mscp/mscp.h>
+#include <vax/mscp/mscpreg.h>
+#include <vax/mscp/mscpvar.h>
+
+#include "ra.h"
+#include "mt.h"
+
+#define b_forw b_hash.le_next
+
+int    mscp_match __P((struct device *, struct cfdata *, void *));
+void   mscp_attach __P((struct device *, struct device *, void *));
+void   mscp_start __P((struct  mscp_softc *));
+int    mscp_init __P((struct  mscp_softc *));
+void   mscp_initds __P((struct mscp_softc *));
+int    mscp_waitstep __P((struct mscp_softc *, int, int));
+
+struct cfattach mscpbus_ca = {
+       sizeof(struct mscp_softc), mscp_match, mscp_attach
+};
+
+struct mscp slavereply;
+
+/*
+ * This function is for delay during init. Some MSCP clone card (Dilog)
+ * can't handle fast read from its registers, and therefore need
+ * a delay between them.
+ */
+
+#define DELAYTEN 1000
+int
+mscp_waitstep(mi, mask, result)
+       struct mscp_softc *mi;
+       int mask, result;
+{
+       int     status = 1;
+
+       if ((*mi->mi_sa & mask) != result) {
+               volatile int count = 0;
+               while ((*mi->mi_sa & mask) != result) {
+                       DELAY(10000);
+                       count += 1;
+                       if (count > DELAYTEN)
+                               break;
+               }
+               if (count > DELAYTEN)
+                       status = 0;
+       }
+       return status;
+}
+
+int
+mscp_match(parent, match, aux)
+       struct device *parent;
+       struct cfdata *match;
+       void *aux;
+{
+       struct  mscp_attach_args *ma = aux;
+
+#if NRA || NRX
+       if (ma->ma_type & MSCPBUS_DISK)
+               return 1;
+#endif
+#if NMT
+       if (ma->ma_type & MSCPBUS_TAPE)
+               return 1;
+#endif
+       return 0;
+};
+
+void
+mscp_attach(parent, self, aux)
+       struct device *parent, *self;
+       void *aux;
+{
+       struct  mscp_attach_args *ma = aux;
+       struct  mscp_softc *mi = (void *)self;
+       volatile struct mscp *mp;
+       volatile int i;
+       int     timeout, next = 0;
+
+       mi->mi_mc = ma->ma_mc;
+       mi->mi_me = NULL;
+       mi->mi_type = ma->ma_type;
+       mi->mi_uuda = ma->ma_uuda;
+       mi->mi_uda = ma->ma_uda;
+       mi->mi_ip = ma->ma_ip;
+       mi->mi_sa = ma->ma_sa;
+       mi->mi_sw = ma->ma_sw;
+       mi->mi_ivec = ma->ma_ivec;
+       mi->mi_adapnr = ma->ma_adapnr;
+       mi->mi_ctlrnr = ma->ma_ctlrnr;
+       *ma->ma_softc = mi;
+       /*
+        * Go out to init the bus, so that we can give commands
+        * to its devices.
+        */
+       mi->mi_cmd.mri_size = NCMD;
+       mi->mi_cmd.mri_desc = mi->mi_uda->mp_ca.ca_cmddsc;
+       mi->mi_cmd.mri_ring = mi->mi_uda->mp_cmd;
+       mi->mi_rsp.mri_size = NRSP;
+       mi->mi_rsp.mri_desc = mi->mi_uda->mp_ca.ca_rspdsc;
+       mi->mi_rsp.mri_ring = mi->mi_uda->mp_rsp;
+       mi->mi_actf = (void *)&mi->mi_actf; /* Circular wait queue */
+       mi->mi_actb = (void *)&mi->mi_actf;
+
+       if (mscp_init(mi)) {
+               printf("%s: can't init, controller hung\n",
+                   mi->mi_dev.dv_xname);
+               return;
+       }
+
+#if NRA
+       if (ma->ma_type & MSCPBUS_DISK) {
+               extern  struct mscp_device ra_device;
+
+               mi->mi_me = &ra_device;
+       }
+#endif
+#if NMT
+       if (ma->ma_type & MSCPBUS_TAPE) {
+               extern  struct mscp_device mt_device;
+
+               mi->mi_me = &mt_device;
+       }
+#endif
+       /*
+        * Go out and search for sub-units on this MSCP bus,
+        * and call config_found for each found.
+        */
+findunit:
+       mp = mscp_getcp(mi, MSCP_DONTWAIT);
+       if (mp == NULL)
+               panic("mscpattach: no packets");
+       mp->mscp_opcode = M_OP_GETUNITST;
+       mp->mscp_unit = next;
+       mp->mscp_modifier = M_GUM_NEXTUNIT;
+       *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
+       slavereply.mscp_opcode = 0;
+
+       i = *mi->mi_ip;  /* Kick off polling */
+       mp = &slavereply;
+       timeout = 1000;
+       while (timeout-- > 0) {
+               DELAY(10000);
+               if (mp->mscp_opcode)
+                       goto gotit;
+       }
+       printf("%s: no response to Get Unit Status request\n",
+           mi->mi_dev.dv_xname);
+       return;
+
+gotit: /*
+        * Got a slave response.  If the unit is there, use it.
+        */
+       switch (mp->mscp_status & M_ST_MASK) {
+
+       case M_ST_SUCCESS:      /* worked */
+       case M_ST_AVAILABLE:    /* found another drive */
+               break;          /* use it */
+
+       case M_ST_OFFLINE:
+               /*
+                * Figure out why it is off line.  It may be because
+                * it is nonexistent, or because it is spun down, or
+                * for some other reason.
+                */
+               switch (mp->mscp_status & ~M_ST_MASK) {
+
+               case M_OFFLINE_UNKNOWN:
+                       /*
+                        * No such drive, and there are none with
+                        * higher unit numbers either, if we are
+                        * using M_GUM_NEXTUNIT.
+                        */
+                       mi->mi_ierr = 3;
+                       return;
+
+               case M_OFFLINE_UNMOUNTED:
+                       /*
+                        * The drive is not spun up.  Use it anyway.
+                        *
+                        * N.B.: this seems to be a common occurrance
+                        * after a power failure.  The first attempt
+                        * to bring it on line seems to spin it up
+                        * (and thus takes several minutes).  Perhaps
+                        * we should note here that the on-line may
+                        * take longer than usual.
+                        */
+                       break;
+
+               default:
+                       /*
+                        * In service, or something else equally unusable.
+                        */
+                       printf("%s: unit %d off line: ", mi->mi_dev.dv_xname,
+                               mp->mscp_unit);
+                       mscp_printevent((struct mscp *)mp);
+                       next++;
+                       goto findunit;
+               }
+               break;
+
+       default:
+               printf("%s: unable to get unit status: ", mi->mi_dev.dv_xname);
+               mscp_printevent((struct mscp *)mp);
+               return;
+       }
+
+       /*
+        * If we get a lower number, we have circulated around all
+        * devices and are finished, otherwise try to find next unit.
+        * We shouldn't ever get this, it's a workaround.
+        */
+       if (mp->mscp_unit < next)
+               return;
+
+       next = mp->mscp_unit + 1;
+       goto findunit;
+}
+
+
+/*
+ * The ctlr gets initialised, normally after boot but may also be 
+ * done if the ctlr gets in an unknown state. Returns 1 if init
+ * fails, 0 otherwise.
+ */
+int
+mscp_init(mi)
+       struct  mscp_softc *mi;
+{
+       struct  mscp *mp;
+       volatile int i;
+       int     status, count;
+       unsigned int j = 0;
+
+       /*
+        * While we are thinking about it, reset the next command
+        * and response indicies.
+        */
+       mi->mi_cmd.mri_next = 0;
+       mi->mi_rsp.mri_next = 0;
+
+       mi->mi_flags |= MSC_IGNOREINTR;
+



Home | Main Index | Thread Index | Old Index