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