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