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