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