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