xref: /netbsd-src/sys/dev/mscp/mscp_subr.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*	$NetBSD: mscp_subr.c,v 1.41 2009/05/12 14:37:59 cegger 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.41 2009/05/12 14:37:59 cegger 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 || 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
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