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