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