xref: /netbsd/sys/dev/mscp/mscp_subr.c (revision 778f5600)
1 /*	$NetBSD: mscp_subr.c,v 1.48 2022/04/07 19:33:38 andvar 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.48 2022/04/07 19:33:38 andvar Exp $");
79 
80 #include <sys/param.h>
81 #include <sys/device.h>
82 #include <sys/buf.h>
83 #include <sys/bufq.h>
84 #include <sys/systm.h>
85 #include <sys/proc.h>
86 #include <sys/kmem.h>
87 
88 #include <sys/bus.h>
89 #include <machine/sid.h>
90 
91 #include <dev/mscp/mscp.h>
92 #include <dev/mscp/mscpreg.h>
93 #include <dev/mscp/mscpvar.h>
94 
95 #include "ra.h"
96 #include "mt.h"
97 
98 #define b_forw	b_hash.le_next
99 
100 int	mscp_match(device_t, cfdata_t, void *);
101 void	mscp_attach(device_t, device_t, void *);
102 void	mscp_start(struct mscp_softc *);
103 int	mscp_init(struct mscp_softc *);
104 void	mscp_initds(struct mscp_softc *);
105 int	mscp_waitstep(struct mscp_softc *, int, int);
106 
107 CFATTACH_DECL_NEW(mscpbus, sizeof(struct mscp_softc),
108     mscp_match, mscp_attach, NULL, NULL);
109 
110 #define	READ_SA		(bus_space_read_2(mi->mi_iot, mi->mi_sah, 0))
111 #define	READ_IP		(bus_space_read_2(mi->mi_iot, mi->mi_iph, 0))
112 #define	WRITE_IP(x)	bus_space_write_2(mi->mi_iot, mi->mi_iph, 0, (x))
113 #define	WRITE_SW(x)	bus_space_write_2(mi->mi_iot, mi->mi_swh, 0, (x))
114 
115 struct	mscp mscp_cold_reply;
116 int	     mscp_cold_unit;
117 
118 #define NITEMS		4
119 
120 static inline void
mscp_free_workitems(struct mscp_softc * mi)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
mscp_waitstep(struct mscp_softc * mi,int mask,int result)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
mscp_match(device_t parent,cfdata_t match,void * aux)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
mscp_attach(device_t parent,device_t self,void * aux)175 mscp_attach(device_t parent, device_t self, void *aux)
176 {
177 	struct	mscp_attach_args *ma = aux;
178 	struct	mscp_softc *mi = device_private(self);
179 	struct mscp *mp2;
180 	volatile struct mscp *mp;
181 	volatile int i;
182 	int	timeout, error, unit;
183 
184 	mi->mi_dev = self;
185 	mi->mi_mc = ma->ma_mc;
186 	mi->mi_me = NULL;
187 	mi->mi_type = ma->ma_type;
188 	mi->mi_uda = ma->ma_uda;
189 	mi->mi_dmat = ma->ma_dmat;
190 	mi->mi_dmam = ma->ma_dmam;
191 	mi->mi_iot = ma->ma_iot;
192 	mi->mi_iph = ma->ma_iph;
193 	mi->mi_sah = ma->ma_sah;
194 	mi->mi_swh = ma->ma_swh;
195 	mi->mi_ivec = ma->ma_ivec;
196 	mi->mi_adapnr = ma->ma_adapnr;
197 	mi->mi_ctlrnr = ma->ma_ctlrnr;
198 	*ma->ma_softc = mi;
199 
200 	mutex_init(&mi->mi_mtx, MUTEX_DEFAULT, IPL_VM);
201 	SLIST_INIT(&mi->mi_freelist);
202 
203 	error = workqueue_create(&mi->mi_wq, "mscp_wq", mscp_worker, NULL,
204 	    PRI_NONE, IPL_VM, 0);
205 	if (error != 0) {
206 		aprint_error_dev(mi->mi_dev, "could not create workqueue");
207 		return;
208 	}
209 
210 	/* Stick some items on the free list to be used in autoconf */
211 	for (i = 0; i < NITEMS; i++) {
212 		struct mscp_work *mw;
213 
214 		mw = kmem_zalloc(sizeof(*mw), KM_SLEEP);
215 		SLIST_INSERT_HEAD(&mi->mi_freelist, mw, mw_list);
216 	}
217 
218 	/*
219 	 * Go out to init the bus, so that we can give commands
220 	 * to its devices.
221 	 */
222 	mi->mi_cmd.mri_size = NCMD;
223 	mi->mi_cmd.mri_desc = mi->mi_uda->mp_ca.ca_cmddsc;
224 	mi->mi_cmd.mri_ring = mi->mi_uda->mp_cmd;
225 	mi->mi_rsp.mri_size = NRSP;
226 	mi->mi_rsp.mri_desc = mi->mi_uda->mp_ca.ca_rspdsc;
227 	mi->mi_rsp.mri_ring = mi->mi_uda->mp_rsp;
228 	bufq_alloc(&mi->mi_resq, "fcfs", 0);
229 
230 	if (mscp_init(mi)) {
231 		aprint_error_dev(mi->mi_dev, "can't init, controller hung\n");
232 		return;
233 	}
234 	for (i = 0; i < NCMD; i++) {
235 		mi->mi_mxiuse |= (1 << i);
236 		if (bus_dmamap_create(mi->mi_dmat, (64*1024), 16, (64*1024),
237 		    0, BUS_DMA_NOWAIT, &mi->mi_xi[i].mxi_dmam)) {
238 			printf("Couldn't alloc dmamap %d\n", i);
239 			return;
240 		}
241 	}
242 
243 
244 #if NRA || NRACD || NRX
245 	if (ma->ma_type & MSCPBUS_DISK) {
246 		extern	struct mscp_device ra_device;
247 
248 		mi->mi_me = &ra_device;
249 	}
250 #endif
251 #if NMT
252 	if (ma->ma_type & MSCPBUS_TAPE) {
253 		extern	struct mscp_device mt_device;
254 
255 		mi->mi_me = &mt_device;
256 	}
257 #endif
258 	/*
259 	 * Go out and search for sub-units on this MSCP bus,
260 	 * and call config_found for each found.
261 	 */
262 	for (unit = 0; unit <= MSCP_MAX_UNIT; ++unit) {
263 		mp = mscp_getcp(mi, MSCP_DONTWAIT);
264 		if (mp == NULL)
265 			panic("mscpattach: no packets");
266 		mp->mscp_opcode = M_OP_GETUNITST;
267 		mp->mscp_unit = unit;
268 		mp->mscp_modifier = M_GUM_NEXTUNIT;
269 		*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
270 		mscp_cold_reply.mscp_opcode = 0;
271 		mscp_cold_unit = mp->mscp_unit;
272 
273 		i = bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
274 		mp = &mscp_cold_reply;
275 		timeout = 1000;
276 
277 		while (!mp->mscp_opcode) {
278 			if ( --timeout == 0) {
279 				printf("%s: no Get Unit Status response\n",
280 				    device_xname(mi->mi_dev));
281 				return;
282 			}
283 			DELAY(10000);
284 		}
285 
286 		/*
287 		 * Got a slave response.  If the unit is there, use it.
288 		 */
289 
290 		/*
291 		 * If we get a lower number, we have circulated around all
292 		 * devices and are finished, otherwise try to find next unit.
293 		 */
294 		if (mp->mscp_unit < unit)
295 			return;
296 		/*
297 		 * If a higher number, use it to skip non-present devices
298 		 */
299 		if (mp->mscp_unit > unit)
300 			unit = mp->mscp_unit;
301 
302 		switch (mp->mscp_status & M_ST_MASK) {
303 
304 		case M_ST_SUCCESS:	/* worked */
305 		case M_ST_AVAILABLE:	/* found another drive */
306 			break;		/* use it */
307 
308 		case M_ST_OFFLINE:
309 			/*
310 			 * Figure out why it is off line.  It may be because
311 			 * it is nonexistent, or because it is spun down, or
312 			 * for some other reason.
313 			 */
314 			switch (mp->mscp_status & ~M_ST_MASK) {
315 
316 			case M_OFFLINE_UNKNOWN:
317 				/*
318 				 * No such drive, and there are none with
319 				 * higher unit numbers either, if we are
320 				 * using M_GUM_NEXTUNIT.
321 				 */
322 				mi->mi_ierr = 3;
323 				break; /* return */
324 
325 			case M_OFFLINE_UNMOUNTED:
326 				/*
327 				 * The drive is not spun up.  Use it anyway.
328 				 *
329 				 * N.B.: this seems to be a common occurrence
330 				 * after a power failure.  The first attempt
331 				 * to bring it on line seems to spin it up
332 				 * (and thus takes several minutes).  Perhaps
333 				 * we should note here that the on-line may
334 				 * take longer than usual.
335 				 */
336 				break;
337 
338 			default:
339 				/*
340 				 * In service, or something else unusable.
341 				 */
342 				printf("%s: unit %d off line: ",
343 				    device_xname(mi->mi_dev), mp->mscp_unit);
344 				mp2 = __UNVOLATILE(mp);
345 				mscp_printevent(mp2);
346 				break;
347 			}
348 			break;
349 
350 		default:
351 			aprint_error_dev(mi->mi_dev,
352 			    "unable to get unit status: ");
353 			mscp_printevent(__UNVOLATILE(mp));
354 			return;
355 		}
356 	}
357 }
358 
359 
360 /*
361  * The ctlr gets initialised, normally after boot but may also be
362  * done if the ctlr gets in an unknown state. Returns 1 if init
363  * fails, 0 otherwise.
364  */
365 int
mscp_init(struct mscp_softc * mi)366 mscp_init(struct mscp_softc *mi)
367 {
368 	struct	mscp *mp;
369 	volatile int i;
370 	int	status, count;
371 	unsigned int j = 0;
372 
373 	/*
374 	 * While we are thinking about it, reset the next command
375 	 * and response indicies.
376 	 */
377 	mi->mi_cmd.mri_next = 0;
378 	mi->mi_rsp.mri_next = 0;
379 
380 	mi->mi_flags |= MSC_IGNOREINTR;
381 
382 	if ((mi->mi_type & MSCPBUS_KDB) == 0)
383 		WRITE_IP(0); /* Kick off */;
384 
385 	status = mscp_waitstep(mi, MP_STEP1, MP_STEP1);/* Wait to it wakes up */
386 	if (status == 0)
387 		return 1; /* Init failed */
388 	if (READ_SA & MP_ERR) {
389 		(*mi->mi_mc->mc_saerror)(device_parent(mi->mi_dev), 0);
390 		return 1;
391 	}
392 
393 	/* step1 */
394 	WRITE_SW(MP_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) |
395 	    MP_IE | (mi->mi_ivec >> 2));
396 	status = mscp_waitstep(mi, STEP1MASK, STEP1GOOD);
397 	if (status == 0) {
398 		(*mi->mi_mc->mc_saerror)(device_parent(mi->mi_dev), 0);
399 		return 1;
400 	}
401 
402 	/* step2 */
403 	WRITE_SW(((mi->mi_dmam->dm_segs[0].ds_addr & 0xffff) +
404 	    offsetof(struct mscp_pack, mp_ca.ca_rspdsc[0])) |
405 	    (vax_cputype == VAX_780 || vax_cputype == VAX_8600 ? MP_PI : 0));
406 	status = mscp_waitstep(mi, STEP2MASK, STEP2GOOD(mi->mi_ivec >> 2));
407 	if (status == 0) {
408 		(*mi->mi_mc->mc_saerror)(device_parent(mi->mi_dev), 0);
409 		return 1;
410 	}
411 
412 	/* step3 */
413 	WRITE_SW((mi->mi_dmam->dm_segs[0].ds_addr >> 16));
414 	status = mscp_waitstep(mi, STEP3MASK, STEP3GOOD);
415 	if (status == 0) {
416 		(*mi->mi_mc->mc_saerror)(device_parent(mi->mi_dev), 0);
417 		return 1;
418 	}
419 	i = READ_SA & 0377;
420 	printf(": version %d model %d\n", i & 15, i >> 4);
421 
422 #define BURST 4 /* XXX */
423 	if (mi->mi_type & MSCPBUS_UDA) {
424 		WRITE_SW(MP_GO | (BURST - 1) << 2);
425 		printf("%s: DMA burst size set to %d\n",
426 		    device_xname(mi->mi_dev), BURST);
427 	}
428 	WRITE_SW(MP_GO);
429 
430 	mscp_initds(mi);
431 	mi->mi_flags &= ~MSC_IGNOREINTR;
432 
433 	/*
434 	 * Set up all necessary info in the bus softc struct, get a
435 	 * mscp packet and set characteristics for this controller.
436 	 */
437 	mi->mi_credits = MSCP_MINCREDITS + 1;
438 	mp = mscp_getcp(mi, MSCP_DONTWAIT);
439 
440 	mi->mi_credits = 0;
441 	mp->mscp_opcode = M_OP_SETCTLRC;
442 	mp->mscp_unit = mp->mscp_modifier = mp->mscp_flags =
443 	    mp->mscp_sccc.sccc_version = mp->mscp_sccc.sccc_hosttimo =
444 	    mp->mscp_sccc.sccc_time = mp->mscp_sccc.sccc_time1 =
445 	    mp->mscp_sccc.sccc_errlgfl = 0;
446 	mp->mscp_sccc.sccc_ctlrflags = M_CF_ATTN | M_CF_MISC | M_CF_THIS;
447 	*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
448 	READ_IP;
449 
450 	count = 0;
451 	while (count < DELAYTEN) {
452 		if (((volatile int)mi->mi_flags & MSC_READY) != 0)
453 			break;
454 		if ((j = READ_SA) & MP_ERR)
455 			goto out;
456 		DELAY(10000);
457 		count += 1;
458 	}
459 	if (count == DELAYTEN) {
460 out:
461 		aprint_error_dev(mi->mi_dev, "couldn't set ctlr characteristics, sa=%x\n", j);
462 		return 1;
463 	}
464 	return 0;
465 }
466 
467 /*
468  * Initialise the various data structures that control the mscp protocol.
469  */
470 void
mscp_initds(struct mscp_softc * mi)471 mscp_initds(struct mscp_softc *mi)
472 {
473 	struct mscp_pack *ud = mi->mi_uda;
474 	struct mscp *mp;
475 	int i;
476 
477 	for (i = 0, mp = ud->mp_rsp; i < NRSP; i++, mp++) {
478 		ud->mp_ca.ca_rspdsc[i] = MSCP_OWN | MSCP_INT |
479 		    (mi->mi_dmam->dm_segs[0].ds_addr +
480 		    offsetof(struct mscp_pack, mp_rsp[i].mscp_cmdref));
481 		mp->mscp_addr = &ud->mp_ca.ca_rspdsc[i];
482 		mp->mscp_msglen = MSCP_MSGLEN;
483 	}
484 	for (i = 0, mp = ud->mp_cmd; i < NCMD; i++, mp++) {
485 		ud->mp_ca.ca_cmddsc[i] = MSCP_INT |
486 		    (mi->mi_dmam->dm_segs[0].ds_addr +
487 		    offsetof(struct mscp_pack, mp_cmd[i].mscp_cmdref));
488 		mp->mscp_addr = &ud->mp_ca.ca_cmddsc[i];
489 		mp->mscp_msglen = MSCP_MSGLEN;
490 		if (mi->mi_type & MSCPBUS_TAPE)
491 			mp->mscp_vcid = 1;
492 	}
493 }
494 
495 static	void mscp_kickaway(struct mscp_softc *);
496 
497 void
mscp_intr(struct mscp_softc * mi)498 mscp_intr(struct mscp_softc *mi)
499 {
500 	struct mscp_pack *ud = mi->mi_uda;
501 
502 	if (mi->mi_flags & MSC_IGNOREINTR)
503 		return;
504 	/*
505 	 * Check for response and command ring transitions.
506 	 */
507 	if (ud->mp_ca.ca_rspint) {
508 		ud->mp_ca.ca_rspint = 0;
509 		mscp_dorsp(mi);
510 	}
511 	if (ud->mp_ca.ca_cmdint) {
512 		ud->mp_ca.ca_cmdint = 0;
513 		MSCP_DOCMD(mi);
514 	}
515 
516 	/*
517 	 * If there are any not-yet-handled request, try them now.
518 	 */
519 	if (bufq_peek(mi->mi_resq))
520 		mscp_kickaway(mi);
521 }
522 
523 int
mscp_print(void * aux,const char * name)524 mscp_print(void *aux, const char *name)
525 {
526 	struct drive_attach_args *da = aux;
527 	struct	mscp *mp = da->da_mp;
528 	int type = mp->mscp_guse.guse_mediaid;
529 
530 	if (name) {
531 		aprint_normal("%c%c", MSCP_MID_CHAR(2, type),
532 		    MSCP_MID_CHAR(1, type));
533 		if (MSCP_MID_ECH(0, type))
534 			aprint_normal("%c", MSCP_MID_CHAR(0, type));
535 		aprint_normal("%d at %s drive %d", MSCP_MID_NUM(type), name,
536 		    mp->mscp_unit);
537 	}
538 	return UNCONF;
539 }
540 
541 /*
542  * common strategy routine for all types of MSCP devices.
543  */
544 void
mscp_strategy(struct buf * bp,device_t usc)545 mscp_strategy(struct buf *bp, device_t usc)
546 {
547 	struct	mscp_softc *mi = device_private(usc);
548 	int s = spluba();
549 
550 	bufq_put(mi->mi_resq, bp);
551 	mscp_kickaway(mi);
552 	splx(s);
553 }
554 
555 
556 void
mscp_kickaway(struct mscp_softc * mi)557 mscp_kickaway(struct mscp_softc *mi)
558 {
559 	struct buf *bp;
560 	struct	mscp *mp;
561 	int next;
562 
563 	while ((bp = bufq_peek(mi->mi_resq)) != NULL) {
564 		/*
565 		 * Ok; we are ready to try to start a xfer. Get a MSCP packet
566 		 * and try to start...
567 		 */
568 		if ((mp = mscp_getcp(mi, MSCP_DONTWAIT)) == NULL) {
569 			if (mi->mi_credits > MSCP_MINCREDITS)
570 				printf("%s: command ring too small\n",
571 				    device_xname(device_parent(mi->mi_dev)));
572 			/*
573 			 * By some (strange) reason we didn't get a MSCP packet.
574 			 * Just return and wait for free packets.
575 			 */
576 			return;
577 		}
578 
579 		if ((next = (ffs(mi->mi_mxiuse) - 1)) < 0)
580 			panic("no mxi buffers");
581 		mi->mi_mxiuse &= ~(1 << next);
582 		if (mi->mi_xi[next].mxi_inuse)
583 			panic("mxi inuse");
584 		/*
585 		 * Set up the MSCP packet and ask the ctlr to start.
586 		 */
587 		mp->mscp_opcode =
588 		    (bp->b_flags & B_READ) ? M_OP_READ : M_OP_WRITE;
589 		mp->mscp_cmdref = next;
590 		mi->mi_xi[next].mxi_bp = bp;
591 		mi->mi_xi[next].mxi_mp = mp;
592 		mi->mi_xi[next].mxi_inuse = 1;
593 		bp->b_resid = next;
594 		(*mi->mi_me->me_fillin)(bp, mp);
595 		(*mi->mi_mc->mc_go)(device_parent(mi->mi_dev),
596 		    &mi->mi_xi[next]);
597 		(void)bufq_get(mi->mi_resq);
598 	}
599 }
600 
601 void
mscp_dgo(struct mscp_softc * mi,struct mscp_xi * mxi)602 mscp_dgo(struct mscp_softc *mi, struct mscp_xi *mxi)
603 {
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 	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
mscp_hexdump(struct mscp * mp)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
mscp_printevent(struct mscp * mp)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
mscp_decodeerror(const char * name,struct mscp * mp,struct mscp_softc * mi)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