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