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