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