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