1 /* 2 * Copyright (c) 1988 Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Chris Torek. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)mscp.c 7.5 (Berkeley) 12/16/90 11 */ 12 13 /* 14 * MSCP generic driver routines 15 */ 16 17 #include "sys/param.h" 18 #include "sys/buf.h" 19 #include "sys/errno.h" 20 #include "sys/dkstat.h" 21 #include "sys/ioctl.h" 22 #include "sys/disklabel.h" 23 #include "sys/syslog.h" 24 25 #include "../uba/ubavar.h" 26 27 #include "mscp.h" 28 #include "mscpvar.h" 29 30 #define PCMD PSWP /* priority for command packet waits */ 31 32 /* 33 * During transfers, mapping info is saved in the buffer's b_resid. 34 */ 35 #define b_info b_resid 36 37 /* 38 * Get a command packet. Second argument is true iff we are 39 * to wait if necessary. Return NULL if none are available and 40 * we cannot wait. 41 */ 42 struct mscp * 43 mscp_getcp(mi, canwait) 44 register struct mscp_info *mi; 45 int canwait; 46 { 47 #define mri (&mi->mi_cmd) 48 register struct mscp *mp; 49 register int i; 50 int s = spl5(); 51 52 again: 53 /* 54 * Ensure that we have some command credits, and 55 * that the next command packet is free. 56 */ 57 if (mi->mi_credits <= MSCP_MINCREDITS) { 58 if (!canwait) { 59 splx(s); 60 return (NULL); 61 } 62 mi->mi_wantcredits = 1; 63 sleep((caddr_t) &mi->mi_wantcredits, PCMD); 64 goto again; 65 } 66 i = mri->mri_next; 67 if (mri->mri_desc[i] & MSCP_OWN) { 68 if (!canwait) { 69 splx(s); 70 return (NULL); 71 } 72 mi->mi_wantcmd = 1; 73 sleep((caddr_t) &mi->mi_wantcmd, PCMD); 74 goto again; 75 } 76 mi->mi_credits--; 77 mri->mri_desc[i] &= ~MSCP_INT; 78 mri->mri_next = (mri->mri_next + 1) % mri->mri_size; 79 splx(s); 80 mp = &mri->mri_ring[i]; 81 82 /* 83 * Initialise some often-zero fields. 84 * ARE THE LAST TWO NECESSARY IN GENERAL? IT SURE WOULD BE 85 * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS. 86 */ 87 mp->mscp_msglen = MSCP_MSGLEN; 88 mp->mscp_flags = 0; 89 mp->mscp_modifier = 0; 90 mp->mscp_seq.seq_bytecount = 0; 91 mp->mscp_seq.seq_buffer = 0; 92 mp->mscp_seq.seq_mapbase = 0; 93 /*???*/ mp->mscp_sccc.sccc_errlgfl = 0; 94 /*???*/ mp->mscp_sccc.sccc_copyspd = 0; 95 return (mp); 96 #undef mri 97 } 98 99 #ifdef AVOID_EMULEX_BUG 100 int mscp_aeb_xor = 0x8000bb80; 101 #endif 102 103 /* 104 * Do a device go. The driver calls this once it has allocated 105 * resources for the transfer. Save the resource information in 106 * bp->b_ubinfo, and finish the MSCP packet. 107 * 108 * N.B.: If we were blocked for some time, the drive could have gone 109 * off line and might still be that way. We should probably handle 110 * such a case by changing this command into an on line request and 111 * not dequeuing the transfer after all. 112 */ 113 mscp_go(mi, mp, info) 114 register struct mscp_info *mi; 115 register struct mscp *mp; 116 int info; 117 { 118 register struct buf *bp, *dp; 119 120 /* 121 * Now is also the time to move the transfer off the 122 * controller and drive queues, and shuffle the drive 123 * queue on the controller queue. The idea is to try 124 * to keep as many drives busy as possible---to deal 125 * the controller's credits out to the drives in a `fair 126 * share' arrangement. (To do this fully would be more 127 * trouble than it is worth, though.) 128 */ 129 dp = mi->mi_tab->b_actf; 130 bp = dp->b_actf; 131 dp->b_actf = bp->av_forw; /* transfer off drive queue */ 132 mi->mi_tab->b_actf = dp->b_forw;/* drive off ctlr queue */ 133 APPEND(dp, mi->mi_tab, b_forw); /* then back again */ 134 135 /* 136 * Move the buffer to the I/O wait queue. 137 */ 138 bp->av_back = mi->mi_wtab.av_back; 139 bp->av_forw = &mi->mi_wtab; 140 mi->mi_wtab.av_back->av_forw = bp; 141 mi->mi_wtab.av_back = bp; 142 143 /* 144 * Save the mapping info, finish the command packet, and give 145 * it to the device. The device's dgo routine should then 146 * initiate polling. 147 */ 148 bp->b_info = info; 149 #ifdef AVOID_EMULEX_BUG 150 /* 151 * The Emulex SC41/MS will occasionally zero the lower half word 152 * of the command reference number. The upper half word remains 153 * intact. To keep running, we convert the buffer address into 154 * a small but nonzero integer that is unique over all pending 155 * transfers, and store that value in the upper half word. To 156 * catch occurrances of the bug (so that we can gripe to Emulex), 157 * we also put a nonzero value in the lower word. 158 */ 159 { 160 register u_int i = mi->mi_nextbp; 161 162 do { /* find a free value */ 163 if (mi->mi_bp[i] == 0) 164 goto found; 165 i = (i + 1) % AEB_MAX_BP; 166 } while (i != mi->mi_nextbp); 167 panic("mscp_go: AEB_MAX_BP too small"); 168 found: 169 mi->mi_bp[i++] = bp; 170 mi->mi_nextbp = i % AEB_MAX_BP; 171 mp->mscp_cmdref = (i << 16) ^ mscp_aeb_xor; 172 } 173 #else 174 mp->mscp_cmdref = (long) bp; 175 #endif 176 *mp->mscp_addr |= MSCP_OWN | MSCP_INT; 177 } 178 179 /* 180 * Handle a response ring transition. 181 */ 182 mscp_dorsp(mi) 183 register struct mscp_info *mi; 184 { 185 register struct uba_device *ui; 186 register struct buf *bp; 187 register struct mscp *mp; 188 register int nextrsp; 189 struct mscp_driver *md = mi->mi_md; 190 char *ctlrname, *drivename; 191 int st, error, info; 192 193 ctlrname = md->md_mname; 194 drivename = md->md_dname; 195 nextrsp = mi->mi_rsp.mri_next; 196 loop: 197 if (mi->mi_rsp.mri_desc[nextrsp] & MSCP_OWN) { 198 /* 199 * No more responses. Remember the next expected 200 * response index. Check to see if we have some 201 * credits back, and wake up sleepers if so. 202 */ 203 mi->mi_rsp.mri_next = nextrsp; 204 if (mi->mi_wantcredits && mi->mi_credits > MSCP_MINCREDITS) { 205 mi->mi_wantcredits = 0; 206 wakeup((caddr_t) &mi->mi_wantcredits); 207 } 208 return; 209 } 210 211 /* 212 * Found a response. Update credit information. If there is 213 * nothing else to do, jump to `done' to get the next response. 214 */ 215 mp = &mi->mi_rsp.mri_ring[nextrsp]; 216 mi->mi_credits += MSCP_CREDITS(mp->mscp_msgtc); 217 switch (MSCP_MSGTYPE(mp->mscp_msgtc)) { 218 219 case MSCPT_SEQ: 220 break; 221 222 case MSCPT_DATAGRAM: 223 (*md->md_dgram)(mi, mp); 224 goto done; 225 226 case MSCPT_CREDITS: 227 goto done; 228 229 case MSCPT_MAINTENANCE: 230 default: 231 printf("%s%d: unit %d: unknown message type 0x%x ignored\n", 232 ctlrname, mi->mi_ctlr, mp->mscp_unit, 233 MSCP_MSGTYPE(mp->mscp_msgtc)); 234 goto done; 235 } 236 237 /* 238 * Controllers are allowed to interrupt as any drive, so we 239 * must check the command before checking for a drive. 240 */ 241 if (mp->mscp_opcode == (M_OP_SETCTLRC | M_OP_END)) { 242 (*md->md_ctlrdone)(mi, mp); 243 goto done; 244 } 245 246 /* 247 * Find the drive info. If there is none, and this is an 248 * available attention response, try configuring a new drive. 249 */ 250 if (mp->mscp_unit > md->md_ndpc) { 251 printf("%s%d: unit %d out of range\n", 252 ctlrname, mi->mi_ctlr, mp->mscp_unit); 253 goto done; 254 } 255 if ((ui = mi->mi_ip[mp->mscp_unit]) == NULL) { 256 if ((*md->md_unconf)(mi, mp) != MSCP_DONE) { 257 printf("%s%d: unit %d not configured, ", 258 ctlrname, mi->mi_ctlr, mp->mscp_unit); 259 if (mp->mscp_opcode == M_OP_AVAILATTN) 260 printf("available attn"); 261 else 262 printf("stray response op 0x%x status 0x%x", 263 mp->mscp_opcode, mp->mscp_status); 264 printf(" ignored\n"); 265 } 266 goto done; 267 } 268 269 /* 270 * Handle individual responses. 271 */ 272 st = mp->mscp_status & M_ST_MASK; 273 error = 0; 274 switch (mp->mscp_opcode) { 275 276 case M_OP_END: 277 /* 278 * The controller presents a bogus END packet when 279 * a read/write command is given with an illegal 280 * block number. This is contrary to the MSCP 281 * specification (ENDs are to be given only for 282 * invalid commands), but that is the way of it. 283 */ 284 if (st == M_ST_INVALCMD && mp->mscp_cmdref != 0) { 285 printf("%s%d: bad lbn (%d)?\n", drivename, 286 ui->ui_unit, mp->mscp_seq.seq_lbn); 287 error = EIO; 288 goto rwend; 289 } 290 goto unknown; 291 292 case M_OP_ONLINE | M_OP_END: 293 /* 294 * Finished an ON LINE request. Call the driver to 295 * find out whether it succeeded. If so, mark it on 296 * line. 297 */ 298 if (ui->ui_flags & UNIT_ONLINE) { 299 printf("%s%d: duplicate ONLINE ignored\n", 300 drivename, ui->ui_unit); 301 break; 302 } 303 if ((*md->md_online)(ui, mp) == MSCP_DONE) 304 ui->ui_flags |= UNIT_ONLINE; 305 break; 306 307 case M_OP_GETUNITST | M_OP_END: 308 /* 309 * Got unit status. Call the driver to find out 310 * whether it succeeded, and if so, mark it. 311 */ 312 if ((*md->md_gotstatus)(ui, mp) == MSCP_DONE) 313 ui->ui_flags |= UNIT_HAVESTATUS; 314 break; 315 316 case M_OP_AVAILATTN: 317 /* 318 * The drive went offline and we did not notice. 319 * Mark it off line now, to force an on line request 320 * next, so we can make sure it is still the same 321 * drive. 322 * 323 * IF THE UDA DRIVER HAS A COMMAND AWAITING UNIBUS 324 * RESOURCES, THAT COMMAND MAY GO OUT BEFORE THE ON 325 * LINE. IS IT WORTH FIXING?? 326 */ 327 ui->ui_flags &= ~(UNIT_ONLINE | UNIT_HAVESTATUS); 328 #ifdef notyet 329 (*md->md_offline)(ui, mp); 330 #endif 331 break; 332 333 case M_OP_READ | M_OP_END: 334 case M_OP_WRITE | M_OP_END: 335 /* 336 * A transfer finished. Get the buffer, and release its 337 * map registers via ubadone(). If the command finished 338 * with an off line or available status, the drive went 339 * off line (the idiot controller does not tell us until 340 * it comes back *on* line, or until we try to use it). 341 */ 342 if (mp->mscp_cmdref == 0) { 343 /* 344 * No buffer means there is a bug somewhere! 345 */ 346 printf("%s%d: io done, but no buffer?\n", 347 drivename, ui->ui_unit); 348 mscp_hexdump(mp); 349 break; 350 } 351 352 rwend: 353 #ifdef AVOID_EMULEX_BUG 354 { 355 register u_short *p = (u_short *) &mp->mscp_cmdref; 356 357 /* 358 * Note any errors on the part of the controller. 359 * The lower word should be zero after exclusive 360 * or'ing with mscp_aeb_xor, and the upper should 361 * then be in the range [1..AEB_MAX_BP]. 362 */ 363 mp->mscp_cmdref ^= mscp_aeb_xor; 364 p[1]--; 365 if (p[1] >= AEB_MAX_BP) 366 panic("unrecoverable Emulex screwup"); 367 if (p[0] == 0) 368 mi->mi_ok++; 369 else { 370 /* 371 * Calculate the expected response, 372 * assuming p[1] is correct. The 373 * actual response is then the expected 374 * response xor p[0]. 375 */ 376 int sb = ((p[1] + 1) << 16) ^ mscp_aeb_xor; 377 378 log(LOG_WARNING, "\ 379 Emulex SC41/MS screwup: %s%d, got %d correct, then changed 0x%x to 0x%x\n", 380 ctlrname, mi->mi_ctlr, 381 mi->mi_ok, sb, sb ^ p[0]); 382 mi->mi_ok = 0; 383 } 384 /* convert index back to buffer, and mark free */ 385 bp = mi->mi_bp[p[1]]; 386 mi->mi_bp[p[1]] = 0; 387 } 388 #else 389 bp = (struct buf *) mp->mscp_cmdref; 390 #ifdef MSCP_PARANOIA 391 { 392 register struct buf *q = mi->mi_wtab.av_forw; 393 394 /* 395 * Ensure that this response corresponds to 396 * some outstanding request. If not, ignore 397 * it entirely. This will likely cause a 398 * Unibus reset soon, after which the controller 399 * just might behave. 400 */ 401 while (q != bp && q != &mi->mi_wtab) 402 q = q->av_forw; 403 if (q != bp) { 404 printf("%s%d: bad response packet ignored\n", 405 ctlrname, mi->mi_ctlr); 406 mscp_hexdump(mp); 407 goto out; 408 } 409 } 410 #endif MSCP_PARANOIA 411 #endif AVOID_EMULEX_BUG 412 413 /* 414 * Mark any error-due-to-bad-LBN (via `goto rwend'). 415 * WHAT STATUS WILL THESE HAVE? IT SURE WOULD BE NICE 416 * IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS. 417 */ 418 if (error) { 419 bp->b_flags |= B_ERROR; 420 bp->b_error = error; 421 } 422 if (st == M_ST_OFFLINE || st == M_ST_AVAILABLE) { 423 ui->ui_flags &= ~(UNIT_ONLINE | UNIT_HAVESTATUS); 424 #ifdef notyet 425 (*md->md_offline)(ui, mp); 426 #endif 427 } 428 429 /* 430 * Unlink the transfer from the wait queue mi_wtab. 431 * If there are no more transfers on the drive queue 432 * for this drive, and it is a profiled disk, turn 433 * off its busy bit. 434 */ 435 bp->av_back->av_forw = bp->av_forw; 436 bp->av_forw->av_back = bp->av_back; 437 if (ui->ui_dk >= 0 && md->md_utab[ui->ui_unit].b_forw == NULL) 438 dk_busy &= ~(1 << ui->ui_dk); 439 440 /* 441 * If the transfer has something to do with bad 442 * block forwarding, let the driver handle the 443 * rest. 444 */ 445 if ((bp->b_flags & B_BAD) != 0 && md->md_bb != NULL) { 446 (*md->md_bb)(ui, mp, bp); 447 goto out; 448 } 449 450 /* 451 * If the transfer failed, give the driver a crack 452 * at fixing things up. 453 */ 454 if (st != M_ST_SUCCESS) { 455 switch ((*md->md_ioerr)(ui, mp, bp)) { 456 457 case MSCP_DONE: /* fixed */ 458 break; 459 460 case MSCP_RESTARTED: /* still working on it */ 461 goto out; 462 463 case MSCP_FAILED: /* no luck */ 464 diskerr(bp, drivename, "hard error", 465 LOG_PRINTF, -1, md->md_lab ? 466 &md->md_lab[ui->ui_unit] : md->md_lab); 467 mscp_printevent(mp); 468 bp->b_flags |= B_ERROR; 469 bp->b_error = EIO; 470 break; 471 } 472 } 473 474 /* 475 * Set the residual count and mark the transfer as 476 * done. If the I/O wait queue is now empty, release 477 * the shared BDP, if any. 478 */ 479 info = bp->b_info; /* we are about to clobber it */ 480 bp->b_resid = bp->b_bcount - mp->mscp_seq.seq_bytecount; 481 (*md->md_iodone)(mi, bp, info); 482 out: 483 break; 484 485 case M_OP_REPLACE | M_OP_END: 486 /* 487 * A replace operation finished. Just let the driver 488 * handle it (if it does replaces). 489 */ 490 if (md->md_replace == NULL) 491 printf("%s%d: bogus REPLACE end\n", 492 drivename, ui->ui_unit); 493 else 494 (*md->md_replace)(ui, mp); 495 break; 496 497 default: 498 /* 499 * If it is not one of the above, we cannot handle it. 500 * (And we should not have received it, for that matter.) 501 */ 502 unknown: 503 printf("%s%d: unknown opcode 0x%x status 0x%x ignored\n", 504 mi->mi_md->md_dname, ui->ui_unit, 505 mp->mscp_opcode, mp->mscp_status); 506 mscp_hexdump(mp); 507 break; 508 } 509 510 /* 511 * If the drive needs to be put back in the controller queue, 512 * do that now. (`bp' below ought to be `dp', but they are all 513 * struct buf *.) Note that b_active was cleared in the driver; 514 * we presume that there is something to be done, hence reassert it. 515 */ 516 if (ui->ui_flags & UNIT_REQUEUE) { 517 bp = &md->md_utab[ui->ui_unit]; 518 if (bp->b_active) panic("mscp_dorsp requeue"); 519 APPEND(bp, mi->mi_tab, b_forw); 520 bp->b_active = 1; 521 ui->ui_flags &= ~UNIT_REQUEUE; 522 } 523 524 done: 525 /* 526 * Give back the response packet, and take a look at the next. 527 */ 528 mp->mscp_msglen = MSCP_MSGLEN; 529 mi->mi_rsp.mri_desc[nextrsp] |= MSCP_OWN; 530 nextrsp = (nextrsp + 1) % mi->mi_rsp.mri_size; 531 goto loop; 532 } 533 534 /* 535 * Dump the entire contents of an MSCP packet in hex. Mainly useful 536 * for debugging.... 537 */ 538 mscp_hexdump(mp) 539 register struct mscp *mp; 540 { 541 register long *p = (long *) mp; 542 register int i = mp->mscp_msglen; 543 544 if (i > 256) /* sanity */ 545 i = 256; 546 i /= sizeof (*p); /* ASSUMES MULTIPLE OF sizeof(long) */ 547 while (--i >= 0) 548 printf("0x%x ", *p++); 549 printf("\n"); 550 } 551 552 /* 553 * Requeue outstanding transfers, e.g., after bus reset. 554 * Also requeue any drives that have on line or unit status 555 * info pending. 556 */ 557 mscp_requeue(mi) 558 struct mscp_info *mi; 559 { 560 register struct uba_device *ui; 561 register struct mscp_driver *md = mi->mi_md; 562 register struct buf *bp, *dp; 563 register int unit; 564 struct buf *nextbp; 565 566 /* 567 * Clear the controller chain. Mark everything un-busy; we 568 * will soon fix any that are in fact busy. 569 */ 570 mi->mi_tab->b_actf = NULL; 571 mi->mi_tab->b_active = 0; 572 for (unit = 0, dp = md->md_utab; unit < md->md_nunits; unit++, dp++) { 573 ui = md->md_dinfo[unit]; 574 if (ui == NULL || !ui->ui_alive || ui->ui_ctlr != mi->mi_ctlr) 575 continue; /* not ours */ 576 dp->b_forw = NULL; 577 dp->b_active = 0; 578 } 579 580 /* 581 * Scan the wait queue, linking buffers onto drive queues. 582 * Note that these must be put at the front of the drive queue, 583 * lest we reorder I/O operations. 584 */ 585 for (bp = mi->mi_wtab.av_back; bp != &mi->mi_wtab; bp = nextbp) { 586 nextbp = bp->av_back; 587 dp = &md->md_utab[minor(bp->b_dev) >> md->md_unitshift]; 588 bp->av_forw = dp->b_actf; 589 if (dp->b_actf == NULL) 590 dp->b_actl = bp; 591 dp->b_actf = bp; 592 } 593 mi->mi_wtab.av_forw = mi->mi_wtab.av_back = &mi->mi_wtab; 594 595 /* 596 * Scan for drives waiting for on line or status responses, 597 * and for drives with pending transfers. Put these on the 598 * controller queue, and mark the controller busy. 599 */ 600 for (unit = 0, dp = md->md_utab; unit < md->md_nunits; unit++, dp++) { 601 ui = md->md_dinfo[unit]; 602 if (ui == NULL || !ui->ui_alive || ui->ui_ctlr != mi->mi_ctlr) 603 continue; 604 ui->ui_flags &= ~(UNIT_HAVESTATUS | UNIT_ONLINE); 605 if ((ui->ui_flags & UNIT_REQUEUE) == 0 && dp->b_actf == NULL) 606 continue; 607 ui->ui_flags &= ~UNIT_REQUEUE; 608 APPEND(dp, mi->mi_tab, b_forw); 609 dp->b_active = 1; 610 mi->mi_tab->b_active = 1; 611 } 612 613 #ifdef AVOID_EMULEX_BUG 614 /* 615 * ... and clear the index-to-buffer table. 616 */ 617 for (unit = 0; unit < AEB_MAX_BP; unit++) 618 mi->mi_bp[unit] = 0; 619 #endif 620 } 621 622 623 /* 624 * MSCP error reporting 625 */ 626 627 /* 628 * Messages for the various subcodes. 629 */ 630 static char unknown_msg[] = "unknown subcode"; 631 632 /* 633 * Subcodes for Success (0) 634 */ 635 static char *succ_msgs[] = { 636 "normal", /* 0 */ 637 "spin down ignored", /* 1 = Spin-Down Ignored */ 638 "still connected", /* 2 = Still Connected */ 639 unknown_msg, 640 "dup. unit #", /* 4 = Duplicate Unit Number */ 641 unknown_msg, 642 unknown_msg, 643 unknown_msg, 644 "already online", /* 8 = Already Online */ 645 unknown_msg, 646 unknown_msg, 647 unknown_msg, 648 unknown_msg, 649 unknown_msg, 650 unknown_msg, 651 unknown_msg, 652 "still online", /* 16 = Still Online */ 653 }; 654 655 /* 656 * Subcodes for Invalid Command (1) 657 */ 658 static char *icmd_msgs[] = { 659 "invalid msg length", /* 0 = Invalid Message Length */ 660 }; 661 662 /* 663 * Subcodes for Command Aborted (2) 664 */ 665 /* none known */ 666 667 /* 668 * Subcodes for Unit Offline (3) 669 */ 670 static char *offl_msgs[] = { 671 "unknown drive", /* 0 = Unknown, or online to other ctlr */ 672 "not mounted", /* 1 = Unmounted, or RUN/STOP at STOP */ 673 "inoperative", /* 2 = Unit Inoperative */ 674 unknown_msg, 675 "duplicate", /* 4 = Duplicate Unit Number */ 676 unknown_msg, 677 unknown_msg, 678 unknown_msg, 679 "in diagnosis", /* 8 = Disabled by FS or diagnostic */ 680 }; 681 682 /* 683 * Subcodes for Unit Available (4) 684 */ 685 /* none known */ 686 687 /* 688 * Subcodes for Media Format Error (5) 689 */ 690 static char *media_fmt_msgs[] = { 691 "fct unread - edc", /* 0 = FCT unreadable */ 692 "invalid sector header",/* 1 = Invalid Sector Header */ 693 "not 512 sectors", /* 2 = Not 512 Byte Sectors */ 694 "not formatted", /* 3 = Not Formatted */ 695 "fct ecc", /* 4 = FCT ECC */ 696 }; 697 698 /* 699 * Subcodes for Write Protected (6) 700 * N.B.: Code 6 subcodes are 7 bits higher than other subcodes 701 * (i.e., bits 12-15). 702 */ 703 static char *wrprot_msgs[] = { 704 unknown_msg, 705 "software", /* 1 = Software Write Protect */ 706 "hardware", /* 2 = Hardware Write Protect */ 707 }; 708 709 /* 710 * Subcodes for Compare Error (7) 711 */ 712 /* none known */ 713 714 /* 715 * Subcodes for Data Error (8) 716 */ 717 static char *data_msgs[] = { 718 "forced error", /* 0 = Forced Error (software) */ 719 unknown_msg, 720 "header compare", /* 2 = Header Compare Error */ 721 "sync timeout", /* 3 = Sync Timeout Error */ 722 unknown_msg, 723 unknown_msg, 724 unknown_msg, 725 "uncorrectable ecc", /* 7 = Uncorrectable ECC */ 726 "1 symbol ecc", /* 8 = 1 bit ECC */ 727 "2 symbol ecc", /* 9 = 2 bit ECC */ 728 "3 symbol ecc", /* 10 = 3 bit ECC */ 729 "4 symbol ecc", /* 11 = 4 bit ECC */ 730 "5 symbol ecc", /* 12 = 5 bit ECC */ 731 "6 symbol ecc", /* 13 = 6 bit ECC */ 732 "7 symbol ecc", /* 14 = 7 bit ECC */ 733 "8 symbol ecc", /* 15 = 8 bit ECC */ 734 }; 735 736 /* 737 * Subcodes for Host Buffer Access Error (9) 738 */ 739 static char *host_buffer_msgs[] = { 740 unknown_msg, 741 "odd xfer addr", /* 1 = Odd Transfer Address */ 742 "odd xfer count", /* 2 = Odd Transfer Count */ 743 "non-exist. memory", /* 3 = Non-Existent Memory */ 744 "memory parity", /* 4 = Memory Parity Error */ 745 }; 746 747 /* 748 * Subcodes for Controller Error (10) 749 */ 750 static char *cntlr_msgs[] = { 751 unknown_msg, 752 "serdes overrun", /* 1 = Serialiser/Deserialiser Overrun */ 753 "edc", /* 2 = Error Detection Code? */ 754 "inconsistant internal data struct",/* 3 = Internal Error */ 755 }; 756 757 /* 758 * Subcodes for Drive Error (11) 759 */ 760 static char *drive_msgs[] = { 761 unknown_msg, 762 "sdi command timeout", /* 1 = SDI Command Timeout */ 763 "ctlr detected protocol",/* 2 = Controller Detected Protocol Error */ 764 "positioner", /* 3 = Positioner Error */ 765 "lost rd/wr ready", /* 4 = Lost R/W Ready Error */ 766 "drive clock dropout", /* 5 = Lost Drive Clock */ 767 "lost recvr ready", /* 6 = Lost Receiver Ready */ 768 "drive detected error", /* 7 = Drive Error */ 769 "ctlr detected pulse or parity",/* 8 = Pulse or Parity Error */ 770 }; 771 772 /* 773 * The following table correlates message codes with the 774 * decoding strings. 775 */ 776 struct code_decode { 777 char *cdc_msg; 778 int cdc_nsubcodes; 779 char **cdc_submsgs; 780 } code_decode[] = { 781 #define SC(m) sizeof (m) / sizeof (m[0]), m 782 "success", SC(succ_msgs), 783 "invalid command", SC(icmd_msgs), 784 "command aborted", 0, 0, 785 "unit offline", SC(offl_msgs), 786 "unit available", 0, 0, 787 "media format error", SC(media_fmt_msgs), 788 "write protected", SC(wrprot_msgs), 789 "compare error", 0, 0, 790 "data error", SC(data_msgs), 791 "host buffer access error", SC(host_buffer_msgs), 792 "controller error", SC(cntlr_msgs), 793 "drive error", SC(drive_msgs), 794 #undef SC 795 }; 796 797 /* 798 * Print the decoded error event from an MSCP error datagram. 799 */ 800 mscp_printevent(mp) 801 struct mscp *mp; 802 { 803 register int event = mp->mscp_event; 804 register struct code_decode *cdc; 805 int c, sc; 806 char *cm, *scm; 807 808 /* 809 * The code is the lower six bits of the event number (aka 810 * status). If that is 6 (write protect), the subcode is in 811 * bits 12-15; otherwise, it is in bits 5-11. 812 * I WONDER WHAT THE OTHER BITS ARE FOR. IT SURE WOULD BE 813 * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS. 814 */ 815 c = event & M_ST_MASK; 816 sc = (c != 6 ? event >> 5 : event >> 12) & 0x7ff; 817 if (c >= sizeof code_decode / sizeof code_decode[0]) 818 cm = "- unknown code", scm = "??"; 819 else { 820 cdc = &code_decode[c]; 821 cm = cdc->cdc_msg; 822 if (sc >= cdc->cdc_nsubcodes) 823 scm = unknown_msg; 824 else 825 scm = cdc->cdc_submsgs[sc]; 826 } 827 printf(" %s (%s) (code %d, subcode %d)\n", cm, scm, c, sc); 828 } 829 830 /* 831 * Print the code and logical block number for an error packet. 832 * THIS IS PROBABLY PECULIAR TO DISK DRIVES. IT SURE WOULD BE 833 * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS. 834 */ 835 mscp_decodeerror(name, ctlr, mp) 836 char *name; 837 int ctlr; 838 register struct mscp *mp; 839 { 840 /* 841 * For bad blocks, mp->mscp_erd.erd_hdr identifies a code and 842 * the logical block number. Code 0 is a regular block; code 6 843 * is a replacement block. The remaining codes are currently 844 * undefined. The code is in the upper four bits of the header 845 * (bits 0-27 are the lbn). 846 */ 847 int issoft = mp->mscp_flags & (M_LF_SUCC | M_LF_CONT); 848 static char *codemsg[16] = { 849 "lbn", "code 1", "code 2", "code 3", 850 "code 4", "code 5", "rbn", "code 7", 851 "code 8", "code 9", "code 10", "code 11", 852 "code 12", "code 13", "code 14", "code 15" 853 }; 854 #define BADCODE(h) (codemsg[(unsigned)(h) >> 28]) 855 #define BADLBN(h) ((h) & 0xfffffff) 856 857 printf("%s%d: %s error datagram%s:", name, ctlr, 858 issoft ? "soft" : "hard", 859 mp->mscp_flags & M_LF_CONT ? " (continuing)" : ""); 860 switch (mp->mscp_format & 0377) { 861 862 case M_FM_CTLRERR: /* controller error */ 863 break; 864 865 case M_FM_BUSADDR: /* host memory access error */ 866 printf(" memory addr 0x%x:", mp->mscp_erd.erd_busaddr); 867 break; 868 869 case M_FM_DISKTRN: 870 printf(" unit %d: level %d retry %d, %s %d:", 871 mp->mscp_unit, 872 mp->mscp_erd.erd_level, mp->mscp_erd.erd_retry, 873 BADCODE(mp->mscp_erd.erd_hdr), 874 BADLBN(mp->mscp_erd.erd_hdr)); 875 break; 876 877 case M_FM_SDI: 878 printf(" unit %d: %s %d:", mp->mscp_unit, 879 BADCODE(mp->mscp_erd.erd_hdr), 880 BADLBN(mp->mscp_erd.erd_hdr)); 881 break; 882 883 case M_FM_SMLDSK: 884 printf(" unit %d: small disk error, cyl %d:", 885 mp->mscp_unit, mp->mscp_erd.erd_sdecyl); 886 break; 887 888 default: 889 printf(" unit %d: unknown error, format 0x%x:", 890 mp->mscp_unit, mp->mscp_format); 891 } 892 mscp_printevent(mp); 893 #undef BADCODE 894 #undef BADLBN 895 } 896