Home | History | Annotate | Line # | Download | only in mscp
mscp_subr.c revision 1.45
      1  1.45    martin /*	$NetBSD: mscp_subr.c,v 1.45 2013/03/26 23:29:11 martin Exp $	*/
      2   1.1     ragge /*
      3   1.1     ragge  * Copyright (c) 1988 Regents of the University of California.
      4   1.1     ragge  * All rights reserved.
      5   1.1     ragge  *
      6   1.1     ragge  * This code is derived from software contributed to Berkeley by
      7   1.1     ragge  * Chris Torek.
      8   1.1     ragge  *
      9   1.1     ragge  * Redistribution and use in source and binary forms, with or without
     10   1.1     ragge  * modification, are permitted provided that the following conditions
     11   1.1     ragge  * are met:
     12   1.1     ragge  * 1. Redistributions of source code must retain the above copyright
     13   1.1     ragge  *    notice, this list of conditions and the following disclaimer.
     14   1.1     ragge  * 2. Redistributions in binary form must reproduce the above copyright
     15   1.1     ragge  *    notice, this list of conditions and the following disclaimer in the
     16   1.1     ragge  *    documentation and/or other materials provided with the distribution.
     17  1.24       agc  * 3. Neither the name of the University nor the names of its contributors
     18  1.24       agc  *    may be used to endorse or promote products derived from this software
     19  1.24       agc  *    without specific prior written permission.
     20  1.24       agc  *
     21  1.24       agc  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22  1.24       agc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  1.24       agc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  1.24       agc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25  1.24       agc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  1.24       agc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  1.24       agc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  1.24       agc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  1.24       agc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  1.24       agc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  1.24       agc  * SUCH DAMAGE.
     32  1.24       agc  *
     33  1.24       agc  *	@(#)mscp.c	7.5 (Berkeley) 12/16/90
     34  1.24       agc  */
     35  1.24       agc 
     36  1.24       agc /*
     37  1.24       agc  * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
     38  1.24       agc  *
     39  1.24       agc  * This code is derived from software contributed to Berkeley by
     40  1.24       agc  * Chris Torek.
     41  1.24       agc  *
     42  1.24       agc  * Redistribution and use in source and binary forms, with or without
     43  1.24       agc  * modification, are permitted provided that the following conditions
     44  1.24       agc  * are met:
     45  1.24       agc  * 1. Redistributions of source code must retain the above copyright
     46  1.24       agc  *    notice, this list of conditions and the following disclaimer.
     47  1.24       agc  * 2. Redistributions in binary form must reproduce the above copyright
     48  1.24       agc  *    notice, this list of conditions and the following disclaimer in the
     49  1.24       agc  *    documentation and/or other materials provided with the distribution.
     50   1.1     ragge  * 3. All advertising materials mentioning features or use of this software
     51   1.1     ragge  *    must display the following acknowledgement:
     52   1.1     ragge  *	This product includes software developed by the University of
     53   1.1     ragge  *	California, Berkeley and its contributors.
     54   1.1     ragge  * 4. Neither the name of the University nor the names of its contributors
     55   1.1     ragge  *    may be used to endorse or promote products derived from this software
     56   1.1     ragge  *    without specific prior written permission.
     57   1.1     ragge  *
     58   1.1     ragge  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     59   1.1     ragge  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     60   1.1     ragge  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     61   1.1     ragge  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     62   1.1     ragge  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     63   1.1     ragge  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     64   1.1     ragge  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     65   1.1     ragge  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     66   1.1     ragge  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     67   1.1     ragge  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     68   1.1     ragge  * SUCH DAMAGE.
     69   1.1     ragge  *
     70   1.1     ragge  *	@(#)mscp.c	7.5 (Berkeley) 12/16/90
     71   1.1     ragge  */
     72   1.1     ragge 
     73   1.1     ragge /*
     74   1.1     ragge  * MSCP generic driver routines
     75   1.1     ragge  */
     76  1.18     lukem 
     77  1.18     lukem #include <sys/cdefs.h>
     78  1.45    martin __KERNEL_RCSID(0, "$NetBSD: mscp_subr.c,v 1.45 2013/03/26 23:29:11 martin Exp $");
     79   1.1     ragge 
     80   1.1     ragge #include <sys/param.h>
     81   1.2     ragge #include <sys/device.h>
     82   1.1     ragge #include <sys/buf.h>
     83  1.25      yamt #include <sys/bufq.h>
     84   1.6     ragge #include <sys/systm.h>
     85   1.6     ragge #include <sys/proc.h>
     86  1.37       mjf #include <sys/kmem.h>
     87   1.1     ragge 
     88  1.34        ad #include <sys/bus.h>
     89   1.1     ragge #include <machine/sid.h>
     90   1.1     ragge 
     91  1.12     ragge #include <dev/mscp/mscp.h>
     92  1.12     ragge #include <dev/mscp/mscpreg.h>
     93  1.12     ragge #include <dev/mscp/mscpvar.h>
     94   1.1     ragge 
     95   1.1     ragge #include "ra.h"
     96   1.2     ragge #include "mt.h"
     97   1.1     ragge 
     98   1.9     ragge #define b_forw	b_hash.le_next
     99   1.1     ragge 
    100  1.41    cegger int	mscp_match(device_t, cfdata_t, void *);
    101  1.41    cegger void	mscp_attach(device_t, device_t, void *);
    102  1.44       chs void	mscp_start(struct mscp_softc *);
    103  1.44       chs int	mscp_init(struct mscp_softc *);
    104  1.26     perry void	mscp_initds(struct mscp_softc *);
    105  1.26     perry int	mscp_waitstep(struct mscp_softc *, int, int);
    106   1.1     ragge 
    107  1.44       chs CFATTACH_DECL_NEW(mscpbus, sizeof(struct mscp_softc),
    108  1.22   thorpej     mscp_match, mscp_attach, NULL, NULL);
    109   1.1     ragge 
    110  1.12     ragge #define	READ_SA		(bus_space_read_2(mi->mi_iot, mi->mi_sah, 0))
    111  1.12     ragge #define	READ_IP		(bus_space_read_2(mi->mi_iot, mi->mi_iph, 0))
    112  1.12     ragge #define	WRITE_IP(x)	bus_space_write_2(mi->mi_iot, mi->mi_iph, 0, (x))
    113  1.12     ragge #define	WRITE_SW(x)	bus_space_write_2(mi->mi_iot, mi->mi_swh, 0, (x))
    114  1.12     ragge 
    115  1.43       abs struct	mscp mscp_cold_reply;
    116  1.43       abs int	     mscp_cold_unit;
    117   1.1     ragge 
    118  1.37       mjf #define NITEMS		4
    119  1.37       mjf 
    120  1.37       mjf static inline void
    121  1.37       mjf mscp_free_workitems(struct mscp_softc *mi)
    122  1.37       mjf {
    123  1.37       mjf 	struct mscp_work *mw;
    124  1.37       mjf 
    125  1.37       mjf 	while (!SLIST_EMPTY(&mi->mi_freelist)) {
    126  1.37       mjf 		mw = SLIST_FIRST(&mi->mi_freelist);
    127  1.37       mjf 		SLIST_REMOVE_HEAD(&mi->mi_freelist, mw_list);
    128  1.37       mjf 		kmem_free(mw, sizeof(*mw));
    129  1.37       mjf 	}
    130  1.37       mjf }
    131  1.37       mjf 
    132   1.1     ragge /*
    133   1.1     ragge  * This function is for delay during init. Some MSCP clone card (Dilog)
    134   1.1     ragge  * can't handle fast read from its registers, and therefore need
    135   1.1     ragge  * a delay between them.
    136   1.1     ragge  */
    137   1.1     ragge 
    138   1.1     ragge #define DELAYTEN 1000
    139   1.1     ragge int
    140  1.39       dsl mscp_waitstep(struct mscp_softc *mi, int mask, int result)
    141   1.1     ragge {
    142   1.1     ragge 	int	status = 1;
    143   1.1     ragge 
    144  1.12     ragge 	if ((READ_SA & mask) != result) {
    145   1.1     ragge 		volatile int count = 0;
    146  1.12     ragge 		while ((READ_SA & mask) != result) {
    147   1.1     ragge 			DELAY(10000);
    148   1.1     ragge 			count += 1;
    149   1.1     ragge 			if (count > DELAYTEN)
    150   1.1     ragge 				break;
    151   1.1     ragge 		}
    152   1.1     ragge 		if (count > DELAYTEN)
    153   1.1     ragge 			status = 0;
    154   1.1     ragge 	}
    155   1.1     ragge 	return status;
    156   1.1     ragge }
    157   1.1     ragge 
    158   1.1     ragge int
    159  1.41    cegger mscp_match(device_t parent, cfdata_t match, void *aux)
    160   1.1     ragge {
    161   1.1     ragge 	struct	mscp_attach_args *ma = aux;
    162   1.1     ragge 
    163  1.42       abs #if NRA || NRACD || NRX
    164   1.1     ragge 	if (ma->ma_type & MSCPBUS_DISK)
    165   1.1     ragge 		return 1;
    166   1.1     ragge #endif
    167   1.1     ragge #if NMT
    168   1.1     ragge 	if (ma->ma_type & MSCPBUS_TAPE)
    169   1.1     ragge 		return 1;
    170   1.1     ragge #endif
    171   1.1     ragge 	return 0;
    172   1.1     ragge };
    173   1.1     ragge 
    174   1.1     ragge void
    175  1.41    cegger mscp_attach(device_t parent, device_t self, void *aux)
    176   1.1     ragge {
    177   1.1     ragge 	struct	mscp_attach_args *ma = aux;
    178  1.32   thorpej 	struct	mscp_softc *mi = device_private(self);
    179  1.28     ragge 	struct mscp *mp2;
    180   1.9     ragge 	volatile struct mscp *mp;
    181   1.1     ragge 	volatile int i;
    182  1.43       abs 	int	timeout, error, unit;
    183   1.1     ragge 
    184  1.44       chs 	mi->mi_dev = self;
    185   1.1     ragge 	mi->mi_mc = ma->ma_mc;
    186   1.1     ragge 	mi->mi_me = NULL;
    187   1.1     ragge 	mi->mi_type = ma->ma_type;
    188   1.1     ragge 	mi->mi_uda = ma->ma_uda;
    189  1.12     ragge 	mi->mi_dmat = ma->ma_dmat;
    190  1.12     ragge 	mi->mi_dmam = ma->ma_dmam;
    191  1.12     ragge 	mi->mi_iot = ma->ma_iot;
    192  1.12     ragge 	mi->mi_iph = ma->ma_iph;
    193  1.12     ragge 	mi->mi_sah = ma->ma_sah;
    194  1.12     ragge 	mi->mi_swh = ma->ma_swh;
    195   1.1     ragge 	mi->mi_ivec = ma->ma_ivec;
    196   1.3     ragge 	mi->mi_adapnr = ma->ma_adapnr;
    197   1.3     ragge 	mi->mi_ctlrnr = ma->ma_ctlrnr;
    198   1.1     ragge 	*ma->ma_softc = mi;
    199  1.37       mjf 
    200  1.37       mjf 	mutex_init(&mi->mi_mtx, MUTEX_DEFAULT, IPL_VM);
    201  1.37       mjf 	SLIST_INIT(&mi->mi_freelist);
    202  1.37       mjf 
    203  1.37       mjf 	error = workqueue_create(&mi->mi_wq, "mscp_wq", mscp_worker, NULL,
    204  1.37       mjf 	    PRI_NONE, IPL_VM, 0);
    205  1.37       mjf 	if (error != 0) {
    206  1.44       chs 		aprint_error_dev(mi->mi_dev, "could not create workqueue");
    207  1.37       mjf 		return;
    208  1.37       mjf 	}
    209  1.37       mjf 
    210  1.37       mjf 	/* Stick some items on the free list to be used in autoconf */
    211  1.37       mjf 	for (i = 0; i < NITEMS; i++) {
    212  1.37       mjf 		struct mscp_work *mw;
    213  1.37       mjf 
    214  1.37       mjf 		if ((mw = kmem_zalloc(sizeof(*mw), KM_SLEEP)) == NULL) {
    215  1.37       mjf 			mscp_free_workitems(mi);
    216  1.44       chs 			aprint_error_dev(mi->mi_dev,
    217  1.37       mjf 			    "failed to allocate memory for work items");
    218  1.37       mjf 			return;
    219  1.37       mjf 		}
    220  1.37       mjf 
    221  1.37       mjf 		SLIST_INSERT_HEAD(&mi->mi_freelist, mw, mw_list);
    222  1.37       mjf 	}
    223  1.37       mjf 
    224   1.1     ragge 	/*
    225   1.1     ragge 	 * Go out to init the bus, so that we can give commands
    226   1.1     ragge 	 * to its devices.
    227   1.1     ragge 	 */
    228   1.9     ragge 	mi->mi_cmd.mri_size = NCMD;
    229   1.9     ragge 	mi->mi_cmd.mri_desc = mi->mi_uda->mp_ca.ca_cmddsc;
    230   1.9     ragge 	mi->mi_cmd.mri_ring = mi->mi_uda->mp_cmd;
    231   1.9     ragge 	mi->mi_rsp.mri_size = NRSP;
    232   1.9     ragge 	mi->mi_rsp.mri_desc = mi->mi_uda->mp_ca.ca_rspdsc;
    233   1.9     ragge 	mi->mi_rsp.mri_ring = mi->mi_uda->mp_rsp;
    234  1.29      yamt 	bufq_alloc(&mi->mi_resq, "fcfs", 0);
    235   1.1     ragge 
    236   1.1     ragge 	if (mscp_init(mi)) {
    237  1.44       chs 		aprint_error_dev(mi->mi_dev, "can't init, controller hung\n");
    238   1.1     ragge 		return;
    239   1.1     ragge 	}
    240  1.12     ragge 	for (i = 0; i < NCMD; i++) {
    241  1.12     ragge 		mi->mi_mxiuse |= (1 << i);
    242  1.14     ragge 		if (bus_dmamap_create(mi->mi_dmat, (64*1024), 16, (64*1024),
    243  1.12     ragge 		    0, BUS_DMA_NOWAIT, &mi->mi_xi[i].mxi_dmam)) {
    244  1.12     ragge 			printf("Couldn't alloc dmamap %d\n", i);
    245  1.12     ragge 			return;
    246  1.12     ragge 		}
    247  1.12     ragge 	}
    248  1.27     perry 
    249   1.1     ragge 
    250  1.42       abs #if NRA || NRACD || NRX
    251   1.1     ragge 	if (ma->ma_type & MSCPBUS_DISK) {
    252   1.1     ragge 		extern	struct mscp_device ra_device;
    253   1.1     ragge 
    254   1.1     ragge 		mi->mi_me = &ra_device;
    255   1.1     ragge 	}
    256   1.1     ragge #endif
    257   1.1     ragge #if NMT
    258   1.1     ragge 	if (ma->ma_type & MSCPBUS_TAPE) {
    259   1.1     ragge 		extern	struct mscp_device mt_device;
    260   1.1     ragge 
    261   1.1     ragge 		mi->mi_me = &mt_device;
    262   1.1     ragge 	}
    263   1.1     ragge #endif
    264   1.1     ragge 	/*
    265   1.1     ragge 	 * Go out and search for sub-units on this MSCP bus,
    266   1.1     ragge 	 * and call config_found for each found.
    267   1.1     ragge 	 */
    268  1.43       abs 	for (unit = 0; unit <= MSCP_MAX_UNIT; ++unit) {
    269  1.43       abs 		mp = mscp_getcp(mi, MSCP_DONTWAIT);
    270  1.43       abs 		if (mp == NULL)
    271  1.43       abs 			panic("mscpattach: no packets");
    272  1.43       abs 		mp->mscp_opcode = M_OP_GETUNITST;
    273  1.43       abs 		mp->mscp_unit = unit;
    274  1.43       abs 		mp->mscp_modifier = M_GUM_NEXTUNIT;
    275  1.43       abs 		*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
    276  1.43       abs 		mscp_cold_reply.mscp_opcode = 0;
    277  1.43       abs 		mscp_cold_unit = mp->mscp_unit;
    278  1.43       abs 
    279  1.43       abs 		i = bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
    280  1.43       abs 		mp = &mscp_cold_reply;
    281  1.43       abs 		timeout = 1000;
    282  1.43       abs 
    283  1.43       abs 		while (!mp->mscp_opcode) {
    284  1.43       abs 			if ( --timeout == 0) {
    285  1.43       abs 				printf("%s: no Get Unit Status response\n",
    286  1.44       chs 				    device_xname(mi->mi_dev));
    287  1.43       abs 				return;
    288  1.43       abs 			}
    289  1.43       abs 			DELAY(10000);
    290  1.43       abs 		}
    291   1.1     ragge 
    292  1.43       abs 		/*
    293  1.43       abs 		 * Got a slave response.  If the unit is there, use it.
    294  1.43       abs 		 */
    295   1.1     ragge 
    296  1.43       abs 		/*
    297  1.43       abs 		 * If we get a lower number, we have circulated around all
    298  1.43       abs 		 * devices and are finished, otherwise try to find next unit.
    299  1.43       abs 		 */
    300  1.43       abs 		if (mp->mscp_unit < unit)
    301  1.43       abs 			return;
    302  1.43       abs 		/*
    303  1.43       abs 		 * If a higher number, use it to skip non-present devices
    304  1.43       abs 		 */
    305  1.43       abs 		if (mp->mscp_unit > unit)
    306  1.43       abs 			unit = mp->mscp_unit;
    307   1.1     ragge 
    308  1.43       abs 		switch (mp->mscp_status & M_ST_MASK) {
    309   1.1     ragge 
    310  1.43       abs 		case M_ST_SUCCESS:	/* worked */
    311  1.43       abs 		case M_ST_AVAILABLE:	/* found another drive */
    312  1.43       abs 			break;		/* use it */
    313   1.9     ragge 
    314  1.43       abs 		case M_ST_OFFLINE:
    315   1.9     ragge 			/*
    316  1.43       abs 			 * Figure out why it is off line.  It may be because
    317  1.43       abs 			 * it is nonexistent, or because it is spun down, or
    318  1.43       abs 			 * for some other reason.
    319   1.9     ragge 			 */
    320  1.43       abs 			switch (mp->mscp_status & ~M_ST_MASK) {
    321  1.43       abs 
    322  1.43       abs 			case M_OFFLINE_UNKNOWN:
    323  1.43       abs 				/*
    324  1.43       abs 				 * No such drive, and there are none with
    325  1.43       abs 				 * higher unit numbers either, if we are
    326  1.43       abs 				 * using M_GUM_NEXTUNIT.
    327  1.43       abs 				 */
    328  1.43       abs 				mi->mi_ierr = 3;
    329  1.43       abs 				break; /* return */
    330  1.43       abs 
    331  1.43       abs 			case M_OFFLINE_UNMOUNTED:
    332  1.43       abs 				/*
    333  1.43       abs 				 * The drive is not spun up.  Use it anyway.
    334  1.43       abs 				 *
    335  1.43       abs 				 * N.B.: this seems to be a common occurrance
    336  1.43       abs 				 * after a power failure.  The first attempt
    337  1.43       abs 				 * to bring it on line seems to spin it up
    338  1.43       abs 				 * (and thus takes several minutes).  Perhaps
    339  1.43       abs 				 * we should note here that the on-line may
    340  1.43       abs 				 * take longer than usual.
    341  1.43       abs 				 */
    342  1.43       abs 				break;
    343   1.9     ragge 
    344  1.43       abs 			default:
    345  1.43       abs 				/*
    346  1.43       abs 				 * In service, or something else unusable.
    347  1.43       abs 				 */
    348  1.43       abs 				printf("%s: unit %d off line: ",
    349  1.44       chs 				    device_xname(mi->mi_dev), mp->mscp_unit);
    350  1.43       abs 				mp2 = __UNVOLATILE(mp);
    351  1.43       abs 				mscp_printevent(mp2);
    352  1.43       abs 				break;
    353  1.43       abs 			}
    354   1.9     ragge 			break;
    355   1.1     ragge 
    356   1.9     ragge 		default:
    357  1.44       chs 			aprint_error_dev(mi->mi_dev,
    358  1.43       abs 			    "unable to get unit status: ");
    359  1.43       abs 			mscp_printevent(__UNVOLATILE(mp));
    360  1.43       abs 			return;
    361   1.9     ragge 		}
    362   1.9     ragge 	}
    363   1.1     ragge }
    364   1.1     ragge 
    365   1.1     ragge 
    366   1.1     ragge /*
    367  1.27     perry  * The ctlr gets initialised, normally after boot but may also be
    368   1.1     ragge  * done if the ctlr gets in an unknown state. Returns 1 if init
    369   1.1     ragge  * fails, 0 otherwise.
    370   1.1     ragge  */
    371   1.1     ragge int
    372  1.38       dsl mscp_init(struct mscp_softc *mi)
    373   1.1     ragge {
    374   1.1     ragge 	struct	mscp *mp;
    375   1.1     ragge 	volatile int i;
    376   1.1     ragge 	int	status, count;
    377   1.6     ragge 	unsigned int j = 0;
    378   1.1     ragge 
    379   1.9     ragge 	/*
    380   1.9     ragge 	 * While we are thinking about it, reset the next command
    381   1.9     ragge 	 * and response indicies.
    382   1.9     ragge 	 */
    383   1.1     ragge 	mi->mi_cmd.mri_next = 0;
    384   1.1     ragge 	mi->mi_rsp.mri_next = 0;
    385   1.1     ragge 
    386   1.1     ragge 	mi->mi_flags |= MSC_IGNOREINTR;
    387   1.6     ragge 
    388   1.6     ragge 	if ((mi->mi_type & MSCPBUS_KDB) == 0)
    389  1.12     ragge 		WRITE_IP(0); /* Kick off */;
    390   1.6     ragge 
    391   1.1     ragge 	status = mscp_waitstep(mi, MP_STEP1, MP_STEP1);/* Wait to it wakes up */
    392   1.1     ragge 	if (status == 0)
    393   1.1     ragge 		return 1; /* Init failed */
    394  1.12     ragge 	if (READ_SA & MP_ERR) {
    395  1.44       chs 		(*mi->mi_mc->mc_saerror)(device_parent(mi->mi_dev), 0);
    396   1.1     ragge 		return 1;
    397   1.1     ragge 	}
    398   1.1     ragge 
    399   1.1     ragge 	/* step1 */
    400  1.12     ragge 	WRITE_SW(MP_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) |
    401  1.12     ragge 	    MP_IE | (mi->mi_ivec >> 2));
    402   1.1     ragge 	status = mscp_waitstep(mi, STEP1MASK, STEP1GOOD);
    403   1.1     ragge 	if (status == 0) {
    404  1.44       chs 		(*mi->mi_mc->mc_saerror)(device_parent(mi->mi_dev), 0);
    405   1.1     ragge 		return 1;
    406   1.1     ragge 	}
    407   1.1     ragge 
    408   1.1     ragge 	/* step2 */
    409  1.27     perry 	WRITE_SW(((mi->mi_dmam->dm_segs[0].ds_addr & 0xffff) +
    410  1.12     ragge 	    offsetof(struct mscp_pack, mp_ca.ca_rspdsc[0])) |
    411  1.12     ragge 	    (vax_cputype == VAX_780 || vax_cputype == VAX_8600 ? MP_PI : 0));
    412   1.1     ragge 	status = mscp_waitstep(mi, STEP2MASK, STEP2GOOD(mi->mi_ivec >> 2));
    413   1.9     ragge 	if (status == 0) {
    414  1.44       chs 		(*mi->mi_mc->mc_saerror)(device_parent(mi->mi_dev), 0);
    415   1.9     ragge 		return 1;
    416   1.9     ragge 	}
    417   1.1     ragge 
    418   1.1     ragge 	/* step3 */
    419  1.12     ragge 	WRITE_SW((mi->mi_dmam->dm_segs[0].ds_addr >> 16));
    420   1.1     ragge 	status = mscp_waitstep(mi, STEP3MASK, STEP3GOOD);
    421  1.27     perry 	if (status == 0) {
    422  1.44       chs 		(*mi->mi_mc->mc_saerror)(device_parent(mi->mi_dev), 0);
    423   1.9     ragge 		return 1;
    424   1.9     ragge 	}
    425  1.12     ragge 	i = READ_SA & 0377;
    426   1.5  christos 	printf(": version %d model %d\n", i & 15, i >> 4);
    427   1.1     ragge 
    428   1.9     ragge #define BURST 4 /* XXX */
    429   1.1     ragge 	if (mi->mi_type & MSCPBUS_UDA) {
    430  1.12     ragge 		WRITE_SW(MP_GO | (BURST - 1) << 2);
    431  1.27     perry 		printf("%s: DMA burst size set to %d\n",
    432  1.44       chs 		    device_xname(mi->mi_dev), BURST);
    433   1.1     ragge 	}
    434  1.12     ragge 	WRITE_SW(MP_GO);
    435   1.1     ragge 
    436   1.1     ragge 	mscp_initds(mi);
    437   1.1     ragge 	mi->mi_flags &= ~MSC_IGNOREINTR;
    438   1.1     ragge 
    439   1.1     ragge 	/*
    440   1.1     ragge 	 * Set up all necessary info in the bus softc struct, get a
    441   1.1     ragge 	 * mscp packet and set characteristics for this controller.
    442   1.1     ragge 	 */
    443   1.1     ragge 	mi->mi_credits = MSCP_MINCREDITS + 1;
    444   1.1     ragge 	mp = mscp_getcp(mi, MSCP_DONTWAIT);
    445   1.2     ragge 
    446   1.1     ragge 	mi->mi_credits = 0;
    447   1.1     ragge 	mp->mscp_opcode = M_OP_SETCTLRC;
    448   1.2     ragge 	mp->mscp_unit = mp->mscp_modifier = mp->mscp_flags =
    449  1.27     perry 	    mp->mscp_sccc.sccc_version = mp->mscp_sccc.sccc_hosttimo =
    450   1.2     ragge 	    mp->mscp_sccc.sccc_time = mp->mscp_sccc.sccc_time1 =
    451   1.2     ragge 	    mp->mscp_sccc.sccc_errlgfl = 0;
    452   1.1     ragge 	mp->mscp_sccc.sccc_ctlrflags = M_CF_ATTN | M_CF_MISC | M_CF_THIS;
    453   1.1     ragge 	*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
    454  1.12     ragge 	i = READ_IP;
    455   1.1     ragge 
    456   1.9     ragge 	count = 0;
    457   1.9     ragge 	while (count < DELAYTEN) {
    458  1.10     ragge 		if (((volatile int)mi->mi_flags & MSC_READY) != 0)
    459   1.9     ragge 			break;
    460  1.12     ragge 		if ((j = READ_SA) & MP_ERR)
    461   1.2     ragge 			goto out;
    462   1.9     ragge 		DELAY(10000);
    463   1.9     ragge 		count += 1;
    464   1.9     ragge 	}
    465   1.1     ragge 	if (count == DELAYTEN) {
    466   1.2     ragge out:
    467  1.44       chs 		aprint_error_dev(mi->mi_dev, "couldn't set ctlr characteristics, sa=%x\n", j);
    468   1.1     ragge 		return 1;
    469   1.1     ragge 	}
    470   1.1     ragge 	return 0;
    471   1.1     ragge }
    472   1.1     ragge 
    473   1.1     ragge /*
    474   1.1     ragge  * Initialise the various data structures that control the mscp protocol.
    475   1.1     ragge  */
    476   1.1     ragge void
    477  1.38       dsl mscp_initds(struct mscp_softc *mi)
    478   1.1     ragge {
    479   1.1     ragge 	struct mscp_pack *ud = mi->mi_uda;
    480   1.1     ragge 	struct mscp *mp;
    481   1.1     ragge 	int i;
    482   1.1     ragge 
    483   1.1     ragge 	for (i = 0, mp = ud->mp_rsp; i < NRSP; i++, mp++) {
    484   1.1     ragge 		ud->mp_ca.ca_rspdsc[i] = MSCP_OWN | MSCP_INT |
    485  1.12     ragge 		    (mi->mi_dmam->dm_segs[0].ds_addr +
    486  1.12     ragge 		    offsetof(struct mscp_pack, mp_rsp[i].mscp_cmdref));
    487   1.1     ragge 		mp->mscp_addr = &ud->mp_ca.ca_rspdsc[i];
    488   1.1     ragge 		mp->mscp_msglen = MSCP_MSGLEN;
    489   1.1     ragge 	}
    490   1.1     ragge 	for (i = 0, mp = ud->mp_cmd; i < NCMD; i++, mp++) {
    491   1.1     ragge 		ud->mp_ca.ca_cmddsc[i] = MSCP_INT |
    492  1.12     ragge 		    (mi->mi_dmam->dm_segs[0].ds_addr +
    493  1.12     ragge 		    offsetof(struct mscp_pack, mp_cmd[i].mscp_cmdref));
    494   1.1     ragge 		mp->mscp_addr = &ud->mp_ca.ca_cmddsc[i];
    495   1.1     ragge 		mp->mscp_msglen = MSCP_MSGLEN;
    496   1.2     ragge 		if (mi->mi_type & MSCPBUS_TAPE)
    497   1.2     ragge 			mp->mscp_vcid = 1;
    498   1.1     ragge 	}
    499   1.1     ragge }
    500   1.1     ragge 
    501  1.12     ragge static	void mscp_kickaway(struct mscp_softc *);
    502  1.12     ragge 
    503   1.1     ragge void
    504  1.38       dsl mscp_intr(struct mscp_softc *mi)
    505   1.1     ragge {
    506   1.1     ragge 	struct mscp_pack *ud = mi->mi_uda;
    507   1.1     ragge 
    508   1.1     ragge 	if (mi->mi_flags & MSC_IGNOREINTR)
    509   1.1     ragge 		return;
    510   1.9     ragge 	/*
    511   1.9     ragge 	 * Check for response and command ring transitions.
    512   1.9     ragge 	 */
    513   1.9     ragge 	if (ud->mp_ca.ca_rspint) {
    514   1.9     ragge 		ud->mp_ca.ca_rspint = 0;
    515   1.9     ragge 		mscp_dorsp(mi);
    516   1.9     ragge 	}
    517   1.9     ragge 	if (ud->mp_ca.ca_cmdint) {
    518   1.9     ragge 		ud->mp_ca.ca_cmdint = 0;
    519   1.9     ragge 		MSCP_DOCMD(mi);
    520   1.9     ragge 	}
    521   1.6     ragge 
    522   1.6     ragge 	/*
    523  1.12     ragge 	 * If there are any not-yet-handled request, try them now.
    524   1.6     ragge 	 */
    525  1.36      yamt 	if (bufq_peek(mi->mi_resq))
    526  1.12     ragge 		mscp_kickaway(mi);
    527   1.1     ragge }
    528   1.1     ragge 
    529   1.1     ragge int
    530  1.38       dsl mscp_print(void *aux, const char *name)
    531   1.1     ragge {
    532   1.9     ragge 	struct drive_attach_args *da = aux;
    533   1.9     ragge 	struct	mscp *mp = da->da_mp;
    534   1.9     ragge 	int type = mp->mscp_guse.guse_mediaid;
    535   1.9     ragge 
    536   1.9     ragge 	if (name) {
    537  1.23   thorpej 		aprint_normal("%c%c", MSCP_MID_CHAR(2, type),
    538  1.23   thorpej 		    MSCP_MID_CHAR(1, type));
    539   1.9     ragge 		if (MSCP_MID_ECH(0, type))
    540  1.23   thorpej 			aprint_normal("%c", MSCP_MID_CHAR(0, type));
    541  1.23   thorpej 		aprint_normal("%d at %s drive %d", MSCP_MID_NUM(type), name,
    542   1.9     ragge 		    mp->mscp_unit);
    543   1.9     ragge 	}
    544   1.1     ragge 	return UNCONF;
    545   1.1     ragge }
    546   1.1     ragge 
    547   1.1     ragge /*
    548   1.1     ragge  * common strategy routine for all types of MSCP devices.
    549   1.1     ragge  */
    550   1.1     ragge void
    551  1.41    cegger mscp_strategy(struct buf *bp, device_t usc)
    552   1.1     ragge {
    553  1.45    martin 	struct	mscp_softc *mi = device_private(usc);
    554  1.17   thorpej 	int s = spluba();
    555  1.12     ragge 
    556  1.36      yamt 	bufq_put(mi->mi_resq, bp);
    557  1.12     ragge 	mscp_kickaway(mi);
    558  1.12     ragge 	splx(s);
    559  1.12     ragge }
    560  1.12     ragge 
    561  1.12     ragge 
    562  1.12     ragge void
    563  1.38       dsl mscp_kickaway(struct mscp_softc *mi)
    564  1.12     ragge {
    565  1.12     ragge 	struct buf *bp;
    566   1.1     ragge 	struct	mscp *mp;
    567  1.12     ragge 	int next;
    568   1.1     ragge 
    569  1.36      yamt 	while ((bp = bufq_peek(mi->mi_resq)) != NULL) {
    570  1.12     ragge 		/*
    571  1.12     ragge 		 * Ok; we are ready to try to start a xfer. Get a MSCP packet
    572  1.12     ragge 		 * and try to start...
    573  1.12     ragge 		 */
    574  1.12     ragge 		if ((mp = mscp_getcp(mi, MSCP_DONTWAIT)) == NULL) {
    575  1.12     ragge 			if (mi->mi_credits > MSCP_MINCREDITS)
    576  1.12     ragge 				printf("%s: command ring too small\n",
    577  1.44       chs 				    device_xname(device_parent(mi->mi_dev)));
    578  1.12     ragge 			/*
    579  1.12     ragge 			 * By some (strange) reason we didn't get a MSCP packet.
    580  1.12     ragge 			 * Just return and wait for free packets.
    581  1.12     ragge 			 */
    582  1.12     ragge 			return;
    583  1.12     ragge 		}
    584  1.27     perry 
    585  1.12     ragge 		if ((next = (ffs(mi->mi_mxiuse) - 1)) < 0)
    586  1.12     ragge 			panic("no mxi buffers");
    587  1.12     ragge 		mi->mi_mxiuse &= ~(1 << next);
    588  1.12     ragge 		if (mi->mi_xi[next].mxi_inuse)
    589  1.12     ragge 			panic("mxi inuse");
    590   1.6     ragge 		/*
    591  1.12     ragge 		 * Set up the MSCP packet and ask the ctlr to start.
    592   1.6     ragge 		 */
    593  1.12     ragge 		mp->mscp_opcode =
    594  1.12     ragge 		    (bp->b_flags & B_READ) ? M_OP_READ : M_OP_WRITE;
    595  1.12     ragge 		mp->mscp_cmdref = next;
    596  1.12     ragge 		mi->mi_xi[next].mxi_bp = bp;
    597  1.12     ragge 		mi->mi_xi[next].mxi_mp = mp;
    598  1.12     ragge 		mi->mi_xi[next].mxi_inuse = 1;
    599  1.12     ragge 		bp->b_resid = next;
    600  1.12     ragge 		(*mi->mi_me->me_fillin)(bp, mp);
    601  1.44       chs 		(*mi->mi_mc->mc_go)(device_parent(mi->mi_dev),
    602  1.31   thorpej 		    &mi->mi_xi[next]);
    603  1.36      yamt 		(void)bufq_get(mi->mi_resq);
    604   1.1     ragge 	}
    605   1.1     ragge }
    606   1.1     ragge 
    607   1.1     ragge void
    608  1.38       dsl mscp_dgo(struct mscp_softc *mi, struct mscp_xi *mxi)
    609   1.1     ragge {
    610   1.1     ragge 	volatile int i;
    611   1.1     ragge 	struct	mscp *mp;
    612   1.1     ragge 
    613   1.9     ragge 	/*
    614   1.9     ragge 	 * Fill in the MSCP packet and move the buffer to the I/O wait queue.
    615   1.9     ragge 	 */
    616  1.12     ragge 	mp = mxi->mxi_mp;
    617  1.12     ragge 	mp->mscp_seq.seq_buffer = mxi->mxi_dmam->dm_segs[0].ds_addr;
    618   1.1     ragge 
    619   1.6     ragge 	*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
    620  1.12     ragge 	i = READ_IP;
    621   1.1     ragge }
    622   1.1     ragge 
    623   1.6     ragge #ifdef DIAGNOSTIC
    624   1.1     ragge /*
    625   1.1     ragge  * Dump the entire contents of an MSCP packet in hex.  Mainly useful
    626   1.1     ragge  * for debugging....
    627   1.1     ragge  */
    628   1.1     ragge void
    629  1.38       dsl mscp_hexdump(struct mscp *mp)
    630   1.1     ragge {
    631  1.15  augustss 	long *p = (long *) mp;
    632  1.15  augustss 	int i = mp->mscp_msglen;
    633   1.1     ragge 
    634   1.1     ragge 	if (i > 256)		/* sanity */
    635   1.1     ragge 		i = 256;
    636   1.1     ragge 	i /= sizeof (*p);	/* ASSUMES MULTIPLE OF sizeof(long) */
    637   1.1     ragge 	while (--i >= 0)
    638   1.5  christos 		printf("0x%x ", (int)*p++);
    639   1.5  christos 	printf("\n");
    640   1.1     ragge }
    641   1.6     ragge #endif
    642   1.1     ragge 
    643   1.1     ragge /*
    644   1.1     ragge  * MSCP error reporting
    645   1.1     ragge  */
    646   1.1     ragge 
    647   1.1     ragge /*
    648   1.1     ragge  * Messages for the various subcodes.
    649   1.1     ragge  */
    650   1.1     ragge static char unknown_msg[] = "unknown subcode";
    651   1.1     ragge 
    652   1.1     ragge /*
    653   1.1     ragge  * Subcodes for Success (0)
    654   1.1     ragge  */
    655  1.28     ragge static const char *succ_msgs[] = {
    656   1.1     ragge 	"normal",		/* 0 */
    657   1.1     ragge 	"spin down ignored",	/* 1 = Spin-Down Ignored */
    658   1.1     ragge 	"still connected",	/* 2 = Still Connected */
    659   1.1     ragge 	unknown_msg,
    660   1.1     ragge 	"dup. unit #",		/* 4 = Duplicate Unit Number */
    661   1.1     ragge 	unknown_msg,
    662   1.1     ragge 	unknown_msg,
    663   1.1     ragge 	unknown_msg,
    664   1.1     ragge 	"already online",	/* 8 = Already Online */
    665   1.1     ragge 	unknown_msg,
    666   1.1     ragge 	unknown_msg,
    667   1.1     ragge 	unknown_msg,
    668   1.1     ragge 	unknown_msg,
    669   1.1     ragge 	unknown_msg,
    670   1.1     ragge 	unknown_msg,
    671   1.1     ragge 	unknown_msg,
    672   1.1     ragge 	"still online",		/* 16 = Still Online */
    673   1.1     ragge };
    674   1.1     ragge 
    675   1.1     ragge /*
    676   1.1     ragge  * Subcodes for Invalid Command (1)
    677   1.1     ragge  */
    678  1.28     ragge static const char *icmd_msgs[] = {
    679   1.1     ragge 	"invalid msg length",	/* 0 = Invalid Message Length */
    680   1.1     ragge };
    681   1.1     ragge 
    682   1.1     ragge /*
    683   1.1     ragge  * Subcodes for Command Aborted (2)
    684   1.1     ragge  */
    685   1.1     ragge /* none known */
    686   1.1     ragge 
    687   1.1     ragge /*
    688   1.1     ragge  * Subcodes for Unit Offline (3)
    689   1.1     ragge  */
    690  1.28     ragge static const char *offl_msgs[] = {
    691   1.1     ragge 	"unknown drive",	/* 0 = Unknown, or online to other ctlr */
    692   1.1     ragge 	"not mounted",		/* 1 = Unmounted, or RUN/STOP at STOP */
    693   1.1     ragge 	"inoperative",		/* 2 = Unit Inoperative */
    694   1.1     ragge 	unknown_msg,
    695   1.1     ragge 	"duplicate",		/* 4 = Duplicate Unit Number */
    696   1.1     ragge 	unknown_msg,
    697   1.1     ragge 	unknown_msg,
    698   1.1     ragge 	unknown_msg,
    699   1.1     ragge 	"in diagnosis",		/* 8 = Disabled by FS or diagnostic */
    700   1.1     ragge };
    701   1.1     ragge 
    702   1.1     ragge /*
    703   1.1     ragge  * Subcodes for Unit Available (4)
    704   1.1     ragge  */
    705   1.1     ragge /* none known */
    706   1.1     ragge 
    707   1.1     ragge /*
    708   1.1     ragge  * Subcodes for Media Format Error (5)
    709   1.1     ragge  */
    710  1.28     ragge static const char *media_fmt_msgs[] = {
    711   1.1     ragge 	"fct unread - edc",	/* 0 = FCT unreadable */
    712   1.1     ragge 	"invalid sector header",/* 1 = Invalid Sector Header */
    713   1.1     ragge 	"not 512 sectors",	/* 2 = Not 512 Byte Sectors */
    714   1.1     ragge 	"not formatted",	/* 3 = Not Formatted */
    715   1.1     ragge 	"fct ecc",		/* 4 = FCT ECC */
    716   1.1     ragge };
    717   1.1     ragge 
    718   1.1     ragge /*
    719   1.1     ragge  * Subcodes for Write Protected (6)
    720   1.1     ragge  * N.B.:  Code 6 subcodes are 7 bits higher than other subcodes
    721   1.1     ragge  * (i.e., bits 12-15).
    722   1.1     ragge  */
    723  1.28     ragge static const char *wrprot_msgs[] = {
    724   1.1     ragge 	unknown_msg,
    725   1.1     ragge 	"software",		/* 1 = Software Write Protect */
    726   1.1     ragge 	"hardware",		/* 2 = Hardware Write Protect */
    727   1.1     ragge };
    728   1.1     ragge 
    729   1.1     ragge /*
    730   1.1     ragge  * Subcodes for Compare Error (7)
    731   1.1     ragge  */
    732   1.1     ragge /* none known */
    733   1.1     ragge 
    734   1.1     ragge /*
    735   1.1     ragge  * Subcodes for Data Error (8)
    736   1.1     ragge  */
    737  1.28     ragge static const char *data_msgs[] = {
    738   1.1     ragge 	"forced error",		/* 0 = Forced Error (software) */
    739   1.1     ragge 	unknown_msg,
    740   1.1     ragge 	"header compare",	/* 2 = Header Compare Error */
    741   1.1     ragge 	"sync timeout",		/* 3 = Sync Timeout Error */
    742   1.1     ragge 	unknown_msg,
    743   1.1     ragge 	unknown_msg,
    744   1.1     ragge 	unknown_msg,
    745   1.1     ragge 	"uncorrectable ecc",	/* 7 = Uncorrectable ECC */
    746   1.1     ragge 	"1 symbol ecc",		/* 8 = 1 bit ECC */
    747   1.1     ragge 	"2 symbol ecc",		/* 9 = 2 bit ECC */
    748   1.1     ragge 	"3 symbol ecc",		/* 10 = 3 bit ECC */
    749   1.1     ragge 	"4 symbol ecc",		/* 11 = 4 bit ECC */
    750   1.1     ragge 	"5 symbol ecc",		/* 12 = 5 bit ECC */
    751   1.1     ragge 	"6 symbol ecc",		/* 13 = 6 bit ECC */
    752   1.1     ragge 	"7 symbol ecc",		/* 14 = 7 bit ECC */
    753   1.1     ragge 	"8 symbol ecc",		/* 15 = 8 bit ECC */
    754   1.1     ragge };
    755   1.1     ragge 
    756   1.1     ragge /*
    757   1.1     ragge  * Subcodes for Host Buffer Access Error (9)
    758   1.1     ragge  */
    759  1.28     ragge static const char *host_buffer_msgs[] = {
    760   1.1     ragge 	unknown_msg,
    761   1.1     ragge 	"odd xfer addr",	/* 1 = Odd Transfer Address */
    762   1.1     ragge 	"odd xfer count",	/* 2 = Odd Transfer Count */
    763   1.1     ragge 	"non-exist. memory",	/* 3 = Non-Existent Memory */
    764   1.1     ragge 	"memory parity",	/* 4 = Memory Parity Error */
    765   1.1     ragge };
    766   1.1     ragge 
    767   1.1     ragge /*
    768   1.1     ragge  * Subcodes for Controller Error (10)
    769   1.1     ragge  */
    770  1.28     ragge static const char *cntlr_msgs[] = {
    771   1.1     ragge 	unknown_msg,
    772   1.1     ragge 	"serdes overrun",	/* 1 = Serialiser/Deserialiser Overrun */
    773   1.1     ragge 	"edc",			/* 2 = Error Detection Code? */
    774  1.33   msaitoh 	"inconsistent internal data struct",/* 3 = Internal Error */
    775   1.1     ragge };
    776   1.1     ragge 
    777   1.1     ragge /*
    778   1.1     ragge  * Subcodes for Drive Error (11)
    779   1.1     ragge  */
    780  1.28     ragge static const char *drive_msgs[] = {
    781   1.1     ragge 	unknown_msg,
    782   1.1     ragge 	"sdi command timeout",	/* 1 = SDI Command Timeout */
    783   1.1     ragge 	"ctlr detected protocol",/* 2 = Controller Detected Protocol Error */
    784   1.1     ragge 	"positioner",		/* 3 = Positioner Error */
    785   1.1     ragge 	"lost rd/wr ready",	/* 4 = Lost R/W Ready Error */
    786   1.1     ragge 	"drive clock dropout",	/* 5 = Lost Drive Clock */
    787   1.1     ragge 	"lost recvr ready",	/* 6 = Lost Receiver Ready */
    788   1.9     ragge 	"drive detected error", /* 7 = Drive Error */
    789   1.1     ragge 	"ctlr detected pulse or parity",/* 8 = Pulse or Parity Error */
    790   1.1     ragge };
    791   1.1     ragge 
    792   1.1     ragge /*
    793   1.1     ragge  * The following table correlates message codes with the
    794   1.1     ragge  * decoding strings.
    795   1.1     ragge  */
    796   1.1     ragge struct code_decode {
    797  1.28     ragge 	const char	*cdc_msg;
    798   1.1     ragge 	int	cdc_nsubcodes;
    799  1.28     ragge 	const char	**cdc_submsgs;
    800   1.1     ragge } code_decode[] = {
    801   1.9     ragge #define SC(m)	sizeof (m) / sizeof (m[0]), m
    802   1.1     ragge 	{"success",			SC(succ_msgs)},
    803   1.1     ragge 	{"invalid command",		SC(icmd_msgs)},
    804   1.1     ragge 	{"command aborted",		0, 0},
    805   1.1     ragge 	{"unit offline",		SC(offl_msgs)},
    806   1.1     ragge 	{"unit available",		0, 0},
    807   1.1     ragge 	{"media format error",		SC(media_fmt_msgs)},
    808   1.1     ragge 	{"write protected",		SC(wrprot_msgs)},
    809   1.1     ragge 	{"compare error",		0, 0},
    810   1.1     ragge 	{"data error",			SC(data_msgs)},
    811   1.1     ragge 	{"host buffer access error",	SC(host_buffer_msgs)},
    812   1.1     ragge 	{"controller error",		SC(cntlr_msgs)},
    813   1.1     ragge 	{"drive error",			SC(drive_msgs)},
    814   1.1     ragge #undef SC
    815   1.1     ragge };
    816   1.1     ragge 
    817   1.1     ragge /*
    818   1.1     ragge  * Print the decoded error event from an MSCP error datagram.
    819   1.1     ragge  */
    820   1.1     ragge void
    821  1.38       dsl mscp_printevent(struct mscp *mp)
    822   1.1     ragge {
    823  1.15  augustss 	int event = mp->mscp_event;
    824  1.15  augustss 	struct code_decode *cdc;
    825   1.1     ragge 	int c, sc;
    826  1.28     ragge 	const char *cm, *scm;
    827   1.1     ragge 
    828   1.1     ragge 	/*
    829   1.1     ragge 	 * The code is the lower six bits of the event number (aka
    830   1.1     ragge 	 * status).  If that is 6 (write protect), the subcode is in
    831   1.1     ragge 	 * bits 12-15; otherwise, it is in bits 5-11.
    832   1.1     ragge 	 * I WONDER WHAT THE OTHER BITS ARE FOR.  IT SURE WOULD BE
    833   1.1     ragge 	 * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS.
    834   1.1     ragge 	 */
    835   1.1     ragge 	c = event & M_ST_MASK;
    836   1.1     ragge 	sc = (c != 6 ? event >> 5 : event >> 12) & 0x7ff;
    837   1.1     ragge 	if (c >= sizeof code_decode / sizeof code_decode[0])
    838   1.1     ragge 		cm = "- unknown code", scm = "??";
    839   1.1     ragge 	else {
    840   1.1     ragge 		cdc = &code_decode[c];
    841   1.1     ragge 		cm = cdc->cdc_msg;
    842   1.1     ragge 		if (sc >= cdc->cdc_nsubcodes)
    843   1.1     ragge 			scm = unknown_msg;
    844   1.1     ragge 		else
    845   1.1     ragge 			scm = cdc->cdc_submsgs[sc];
    846   1.1     ragge 	}
    847   1.5  christos 	printf(" %s (%s) (code %d, subcode %d)\n", cm, scm, c, sc);
    848   1.1     ragge }
    849   1.1     ragge 
    850  1.28     ragge static const char *codemsg[16] = {
    851   1.2     ragge 	"lbn", "code 1", "code 2", "code 3",
    852   1.2     ragge 	"code 4", "code 5", "rbn", "code 7",
    853   1.2     ragge 	"code 8", "code 9", "code 10", "code 11",
    854   1.2     ragge 	"code 12", "code 13", "code 14", "code 15"
    855   1.2     ragge };
    856   1.1     ragge /*
    857   1.1     ragge  * Print the code and logical block number for an error packet.
    858   1.1     ragge  * THIS IS PROBABLY PECULIAR TO DISK DRIVES.  IT SURE WOULD BE
    859   1.1     ragge  * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS.
    860   1.1     ragge  */
    861   1.2     ragge int
    862  1.38       dsl mscp_decodeerror(const char *name, struct mscp *mp, struct mscp_softc *mi)
    863   1.1     ragge {
    864   1.2     ragge 	int issoft;
    865  1.27     perry 	/*
    866   1.2     ragge 	 * We will get three sdi errors of type 11 after autoconfig
    867   1.2     ragge 	 * is finished; depending of searching for non-existing units.
    868   1.2     ragge 	 * How can we avoid this???
    869   1.2     ragge 	 */
    870   1.2     ragge 	if (((mp->mscp_event & M_ST_MASK) == 11) && (mi->mi_ierr++ < 3))
    871   1.2     ragge 		return 1;
    872   1.1     ragge 	/*
    873   1.1     ragge 	 * For bad blocks, mp->mscp_erd.erd_hdr identifies a code and
    874   1.1     ragge 	 * the logical block number.  Code 0 is a regular block; code 6
    875   1.1     ragge 	 * is a replacement block.  The remaining codes are currently
    876   1.1     ragge 	 * undefined.  The code is in the upper four bits of the header
    877   1.1     ragge 	 * (bits 0-27 are the lbn).
    878   1.1     ragge 	 */
    879   1.2     ragge 	issoft = mp->mscp_flags & (M_LF_SUCC | M_LF_CONT);
    880   1.1     ragge #define BADCODE(h)	(codemsg[(unsigned)(h) >> 28])
    881   1.1     ragge #define BADLBN(h)	((h) & 0xfffffff)
    882   1.1     ragge 
    883   1.5  christos 	printf("%s: drive %d %s error datagram%s:", name, mp->mscp_unit,
    884   1.1     ragge 		issoft ? "soft" : "hard",
    885   1.1     ragge 		mp->mscp_flags & M_LF_CONT ? " (continuing)" : "");
    886   1.1     ragge 	switch (mp->mscp_format & 0377) {
    887   1.1     ragge 
    888   1.1     ragge 	case M_FM_CTLRERR:	/* controller error */
    889   1.1     ragge 		break;
    890   1.1     ragge 
    891   1.1     ragge 	case M_FM_BUSADDR:	/* host memory access error */
    892   1.5  christos 		printf(" memory addr 0x%x:", (int)mp->mscp_erd.erd_busaddr);
    893   1.1     ragge 		break;
    894   1.1     ragge 
    895   1.1     ragge 	case M_FM_DISKTRN:
    896   1.5  christos 		printf(" unit %d: level %d retry %d, %s %d:",
    897   1.1     ragge 			mp->mscp_unit,
    898   1.1     ragge 			mp->mscp_erd.erd_level, mp->mscp_erd.erd_retry,
    899   1.1     ragge 			BADCODE(mp->mscp_erd.erd_hdr),
    900   1.1     ragge 			(int)BADLBN(mp->mscp_erd.erd_hdr));
    901   1.1     ragge 		break;
    902   1.1     ragge 
    903   1.1     ragge 	case M_FM_SDI:
    904   1.5  christos 		printf(" unit %d: %s %d:", mp->mscp_unit,
    905   1.1     ragge 			BADCODE(mp->mscp_erd.erd_hdr),
    906   1.1     ragge 			(int)BADLBN(mp->mscp_erd.erd_hdr));
    907   1.1     ragge 		break;
    908   1.1     ragge 
    909   1.1     ragge 	case M_FM_SMLDSK:
    910   1.5  christos 		printf(" unit %d: small disk error, cyl %d:",
    911   1.1     ragge 			mp->mscp_unit, mp->mscp_erd.erd_sdecyl);
    912   1.1     ragge 		break;
    913   1.1     ragge 
    914   1.2     ragge 	case M_FM_TAPETRN:
    915   1.5  christos 		printf(" unit %d: tape transfer error, grp 0x%x event 0%o:",
    916   1.2     ragge 		    mp->mscp_unit, mp->mscp_erd.erd_sdecyl, mp->mscp_event);
    917   1.2     ragge 		break;
    918   1.2     ragge 
    919   1.2     ragge 	case M_FM_STIERR:
    920   1.5  christos 		printf(" unit %d: STI error, event 0%o:", mp->mscp_unit,
    921   1.2     ragge 		    mp->mscp_event);
    922   1.2     ragge 		break;
    923   1.2     ragge 
    924   1.1     ragge 	default:
    925   1.5  christos 		printf(" unit %d: unknown error, format 0x%x:",
    926   1.1     ragge 			mp->mscp_unit, mp->mscp_format);
    927   1.1     ragge 	}
    928   1.1     ragge 	mscp_printevent(mp);
    929   1.2     ragge 	return 0;
    930   1.1     ragge #undef BADCODE
    931   1.1     ragge #undef BADLBN
    932   1.1     ragge }
    933