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