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