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