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