1 /* up.c 4.66 83/02/10 */ 2 3 #include "up.h" 4 #if NSC > 0 5 /* 6 * UNIBUS disk driver with: 7 * overlapped seeks, 8 * ECC recovery, and 9 * bad sector forwarding. 10 * 11 * TODO: 12 * Check that offset recovery code works 13 */ 14 #include "../machine/pte.h" 15 16 #include "../h/param.h" 17 #include "../h/systm.h" 18 #include "../h/dk.h" 19 #include "../h/dkbad.h" 20 #include "../h/buf.h" 21 #include "../h/conf.h" 22 #include "../h/dir.h" 23 #include "../h/user.h" 24 #include "../h/map.h" 25 #include "../h/vm.h" 26 #include "../h/cmap.h" 27 #include "../h/uio.h" 28 29 #include "../vax/cpu.h" 30 #include "../vax/nexus.h" 31 #include "../vaxuba/ubavar.h" 32 #include "../vaxuba/ubareg.h" 33 #include "../vaxuba/upreg.h" 34 35 struct up_softc { 36 int sc_softas; 37 int sc_ndrive; 38 int sc_wticks; 39 int sc_recal; 40 } up_softc[NSC]; 41 42 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ 43 struct size { 44 daddr_t nblocks; 45 int cyloff; 46 } up_sizes[8] = { 47 15884, 0, /* A=cyl 0 thru 26 */ 48 33440, 27, /* B=cyl 27 thru 81 */ 49 495520, 0, /* C=cyl 0 thru 814 */ 50 15884, 562, /* D=cyl 562 thru 588 */ 51 55936, 589, /* E=cyl 589 thru 680 */ 52 81376, 681, /* F=cyl 681 thru 814 */ 53 153728, 562, /* G=cyl 562 thru 814 */ 54 291346, 82, /* H=cyl 82 thru 561 */ 55 }, fj_sizes[8] = { 56 15884, 0, /* A=cyl 0 thru 49 */ 57 33440, 50, /* B=cyl 50 thru 154 */ 58 263360, 0, /* C=cyl 0 thru 822 */ 59 0, 0, 60 0, 0, 61 0, 0, 62 0, 0, 63 213664, 155, /* H=cyl 155 thru 822 */ 64 }, upam_sizes[8] = { 65 15884, 0, /* A=cyl 0 thru 31 */ 66 33440, 32, /* B=cyl 32 thru 97 */ 67 524288, 0, /* C=cyl 0 thru 1023 */ 68 27786, 668, 69 27786, 723, 70 125440, 778, 71 181760, 668, /* G=cyl 668 thru 1022 */ 72 291346, 98, /* H=cyl 98 thru 667 */ 73 }; 74 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ 75 76 /* 77 * On a 780 upSDIST could be 2, but 78 * in the interest of 750's... 79 */ 80 #define _upSDIST 3 /* 1.5 msec */ 81 #define _upRDIST 4 /* 2.0 msec */ 82 83 int upSDIST = _upSDIST; 84 int upRDIST = _upRDIST; 85 86 int upprobe(), upslave(), upattach(), updgo(), upintr(); 87 struct uba_ctlr *upminfo[NSC]; 88 struct uba_device *updinfo[NUP]; 89 #define UPIPUNITS 8 90 struct uba_device *upip[NSC][UPIPUNITS]; /* fuji w/fixed head gives n,n+4 */ 91 92 u_short upstd[] = { 0776700, 0774400, 0776300, 0 }; 93 struct uba_driver scdriver = 94 { upprobe, upslave, upattach, updgo, upstd, "up", updinfo, "sc", upminfo }; 95 struct buf uputab[NUP]; 96 char upinit[NUP]; 97 98 struct upst { 99 short nsect; 100 short ntrak; 101 short nspc; 102 short ncyl; 103 struct size *sizes; 104 } upst[] = { 105 32, 19, 32*19, 823, up_sizes, /* 9300/cdc */ 106 /* 9300 actually has 815 cylinders... */ 107 32, 10, 32*10, 823, fj_sizes, /* fujitsu 160m */ 108 32, 16, 32*16, 1024, upam_sizes, /* ampex capricorn */ 109 }; 110 111 u_char up_offset[16] = { 112 UPOF_P400, UPOF_M400, UPOF_P400, UPOF_M400, 113 UPOF_P800, UPOF_M800, UPOF_P800, UPOF_M800, 114 UPOF_P1200, UPOF_M1200, UPOF_P1200, UPOF_M1200, 115 0, 0, 0, 0 116 }; 117 118 struct buf rupbuf[NUP]; 119 struct buf bupbuf[NUP]; 120 struct dkbad upbad[NUP]; 121 122 #define b_cylin b_resid 123 124 #ifdef INTRLVE 125 daddr_t dkblock(); 126 #endif 127 128 int upwstart, upwatch(); /* Have started guardian */ 129 int upseek; 130 int upwaitdry; 131 132 /*ARGSUSED*/ 133 upprobe(reg) 134 caddr_t reg; 135 { 136 register int br, cvec; 137 138 #ifdef lint 139 br = 0; cvec = br; br = cvec; 140 #endif 141 ((struct updevice *)reg)->upcs1 = UP_IE|UP_RDY; 142 DELAY(10); 143 ((struct updevice *)reg)->upcs1 = 0; 144 return (sizeof (struct updevice)); 145 } 146 147 upslave(ui, reg) 148 struct uba_device *ui; 149 caddr_t reg; 150 { 151 register struct updevice *upaddr = (struct updevice *)reg; 152 153 upaddr->upcs1 = 0; /* conservative */ 154 upaddr->upcs2 = ui->ui_slave; 155 upaddr->upcs1 = UP_NOP|UP_GO; 156 if (upaddr->upcs2&UPCS2_NED) { 157 upaddr->upcs1 = UP_DCLR|UP_GO; 158 return (0); 159 } 160 return (1); 161 } 162 163 upattach(ui) 164 register struct uba_device *ui; 165 { 166 register struct updevice *upaddr; 167 168 if (upwstart == 0) { 169 timeout(upwatch, (caddr_t)0, hz); 170 upwstart++; 171 } 172 if (ui->ui_dk >= 0) 173 dk_mspw[ui->ui_dk] = .0000020345; 174 upip[ui->ui_ctlr][ui->ui_slave] = ui; 175 up_softc[ui->ui_ctlr].sc_ndrive++; 176 upaddr = (struct updevice *)ui->ui_addr; 177 upaddr->upcs1 = 0; 178 upaddr->upcs2 = ui->ui_slave; 179 upaddr->uphr = UPHR_MAXTRAK; 180 if (upaddr->uphr == 9) 181 ui->ui_type = 1; /* fujitsu hack */ 182 else if (upaddr->uphr == 15) 183 ui->ui_type = 2; /* ampex hack */ 184 upaddr->upcs2 = UPCS2_CLR; 185 } 186 187 upopen(dev) 188 dev_t dev; 189 { 190 register int unit = minor(dev) >> 3; 191 register struct uba_device *ui; 192 193 if (unit >= NUP || (ui = updinfo[unit]) == 0 || ui->ui_alive == 0) 194 return (ENXIO); 195 return (0); 196 } 197 198 upstrategy(bp) 199 register struct buf *bp; 200 { 201 register struct uba_device *ui; 202 register struct upst *st; 203 register int unit; 204 register struct buf *dp; 205 int xunit = minor(bp->b_dev) & 07; 206 long bn, sz; 207 208 sz = (bp->b_bcount+511) >> 9; 209 unit = dkunit(bp); 210 if (unit >= NUP) 211 goto bad; 212 ui = updinfo[unit]; 213 if (ui == 0 || ui->ui_alive == 0) 214 goto bad; 215 st = &upst[ui->ui_type]; 216 if (bp->b_blkno < 0 || 217 (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks) 218 goto bad; 219 bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff; 220 (void) spl5(); 221 dp = &uputab[ui->ui_unit]; 222 disksort(dp, bp); 223 if (dp->b_active == 0) { 224 (void) upustart(ui); 225 bp = &ui->ui_mi->um_tab; 226 if (bp->b_actf && bp->b_active == 0) 227 (void) upstart(ui->ui_mi); 228 } 229 (void) spl0(); 230 return; 231 232 bad: 233 bp->b_flags |= B_ERROR; 234 iodone(bp); 235 return; 236 } 237 238 /* 239 * Unit start routine. 240 * Seek the drive to be where the data is 241 * and then generate another interrupt 242 * to actually start the transfer. 243 * If there is only one drive on the controller, 244 * or we are very close to the data, don't 245 * bother with the search. If called after 246 * searching once, don't bother to look where 247 * we are, just queue for transfer (to avoid 248 * positioning forever without transferrring.) 249 */ 250 upustart(ui) 251 register struct uba_device *ui; 252 { 253 register struct buf *bp, *dp; 254 register struct uba_ctlr *um; 255 register struct updevice *upaddr; 256 register struct upst *st; 257 daddr_t bn; 258 int sn, csn; 259 /* 260 * The SC21 cancels commands if you just say 261 * cs1 = UP_IE 262 * so we are cautious about handling of cs1. 263 * Also don't bother to clear as bits other than in upintr(). 264 */ 265 int didie = 0; 266 267 if (ui == 0) 268 return (0); 269 um = ui->ui_mi; 270 dk_busy &= ~(1<<ui->ui_dk); 271 dp = &uputab[ui->ui_unit]; 272 if ((bp = dp->b_actf) == NULL) 273 goto out; 274 /* 275 * If the controller is active, just remember 276 * that this device would like to be positioned... 277 * if we tried to position now we would confuse the SC21. 278 */ 279 if (um->um_tab.b_active) { 280 up_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave; 281 return (0); 282 } 283 /* 284 * If we have already positioned this drive, 285 * then just put it on the ready queue. 286 */ 287 if (dp->b_active) 288 goto done; 289 dp->b_active = 1; 290 upaddr = (struct updevice *)um->um_addr; 291 upaddr->upcs2 = ui->ui_slave; 292 /* 293 * If drive has just come up, 294 * setup the pack. 295 */ 296 if ((upaddr->upds & UPDS_VV) == 0 || upinit[ui->ui_unit] == 0) { 297 struct buf *bbp = &bupbuf[ui->ui_unit]; 298 299 /* SHOULD WARN SYSTEM THAT THIS HAPPENED */ 300 upinit[ui->ui_unit] = 1; 301 upaddr->upcs1 = UP_IE|UP_DCLR|UP_GO; 302 upaddr->upcs1 = UP_IE|UP_PRESET|UP_GO; 303 upaddr->upof = UPOF_FMT22; 304 didie = 1; 305 st = &upst[ui->ui_type]; 306 bbp->b_flags = B_READ|B_BUSY; 307 bbp->b_dev = bp->b_dev; 308 bbp->b_bcount = 512; 309 bbp->b_un.b_addr = (caddr_t)&upbad[ui->ui_unit]; 310 bbp->b_blkno = st->ncyl * st->nspc - st->nsect; 311 bbp->b_cylin = st->ncyl - 1; 312 dp->b_actf = bbp; 313 bbp->av_forw = bp; 314 bp = bbp; 315 } 316 /* 317 * If drive is offline, forget about positioning. 318 */ 319 if ((upaddr->upds & (UPDS_DPR|UPDS_MOL)) != (UPDS_DPR|UPDS_MOL)) 320 goto done; 321 /* 322 * If there is only one drive, 323 * dont bother searching. 324 */ 325 if (up_softc[um->um_ctlr].sc_ndrive == 1) 326 goto done; 327 /* 328 * Figure out where this transfer is going to 329 * and see if we are close enough to justify not searching. 330 */ 331 st = &upst[ui->ui_type]; 332 bn = dkblock(bp); 333 sn = bn%st->nspc; 334 sn = (sn + st->nsect - upSDIST) % st->nsect; 335 if (bp->b_cylin - upaddr->updc) 336 goto search; /* Not on-cylinder */ 337 else if (upseek) 338 goto done; /* Ok just to be on-cylinder */ 339 csn = (upaddr->upla>>6) - sn - 1; 340 if (csn < 0) 341 csn += st->nsect; 342 if (csn > st->nsect - upRDIST) 343 goto done; 344 search: 345 upaddr->updc = bp->b_cylin; 346 /* 347 * Not on cylinder at correct position, 348 * seek/search. 349 */ 350 if (upseek) 351 upaddr->upcs1 = UP_IE|UP_SEEK|UP_GO; 352 else { 353 upaddr->upda = sn; 354 upaddr->upcs1 = UP_IE|UP_SEARCH|UP_GO; 355 } 356 didie = 1; 357 /* 358 * Mark unit busy for iostat. 359 */ 360 if (ui->ui_dk >= 0) { 361 dk_busy |= 1<<ui->ui_dk; 362 dk_seek[ui->ui_dk]++; 363 } 364 goto out; 365 done: 366 /* 367 * Device is ready to go. 368 * Put it on the ready queue for the controller 369 * (unless its already there.) 370 */ 371 if (dp->b_active != 2) { 372 dp->b_forw = NULL; 373 if (um->um_tab.b_actf == NULL) 374 um->um_tab.b_actf = dp; 375 else 376 um->um_tab.b_actl->b_forw = dp; 377 um->um_tab.b_actl = dp; 378 dp->b_active = 2; 379 } 380 out: 381 return (didie); 382 } 383 384 /* 385 * Start up a transfer on a drive. 386 */ 387 upstart(um) 388 register struct uba_ctlr *um; 389 { 390 register struct buf *bp, *dp; 391 register struct uba_device *ui; 392 register struct updevice *upaddr; 393 struct upst *st; 394 daddr_t bn; 395 int dn, sn, tn, cmd, waitdry; 396 397 loop: 398 /* 399 * Pull a request off the controller queue 400 */ 401 if ((dp = um->um_tab.b_actf) == NULL) 402 return (0); 403 if ((bp = dp->b_actf) == NULL) { 404 um->um_tab.b_actf = dp->b_forw; 405 goto loop; 406 } 407 /* 408 * Mark controller busy, and 409 * determine destination of this request. 410 */ 411 um->um_tab.b_active++; 412 ui = updinfo[dkunit(bp)]; 413 bn = dkblock(bp); 414 dn = ui->ui_slave; 415 st = &upst[ui->ui_type]; 416 sn = bn%st->nspc; 417 tn = sn/st->nsect; 418 sn %= st->nsect; 419 upaddr = (struct updevice *)ui->ui_addr; 420 /* 421 * Select drive if not selected already. 422 */ 423 if ((upaddr->upcs2&07) != dn) 424 upaddr->upcs2 = dn; 425 /* 426 * Check that it is ready and online 427 */ 428 waitdry = 0; 429 while ((upaddr->upds&UPDS_DRY) == 0) { 430 printf("up%d: ds wait ds=%o\n",dkunit(bp),upaddr->upds); 431 if (++waitdry > 512) 432 break; 433 upwaitdry++; 434 } 435 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { 436 printf("up%d: not ready", dkunit(bp)); 437 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { 438 printf("\n"); 439 um->um_tab.b_active = 0; 440 um->um_tab.b_errcnt = 0; 441 dp->b_actf = bp->av_forw; 442 dp->b_active = 0; 443 bp->b_flags |= B_ERROR; 444 iodone(bp); 445 goto loop; 446 } 447 /* 448 * Oh, well, sometimes this 449 * happens, for reasons unknown. 450 */ 451 printf(" (flakey)\n"); 452 } 453 /* 454 * Setup for the transfer, and get in the 455 * UNIBUS adaptor queue. 456 */ 457 upaddr->updc = bp->b_cylin; 458 upaddr->upda = (tn << 8) + sn; 459 upaddr->upwc = -bp->b_bcount / sizeof (short); 460 if (bp->b_flags & B_READ) 461 cmd = UP_IE|UP_RCOM|UP_GO; 462 else 463 cmd = UP_IE|UP_WCOM|UP_GO; 464 um->um_cmd = cmd; 465 (void) ubago(ui); 466 return (1); 467 } 468 469 /* 470 * Now all ready to go, stuff the registers. 471 */ 472 updgo(um) 473 struct uba_ctlr *um; 474 { 475 register struct updevice *upaddr = (struct updevice *)um->um_addr; 476 477 um->um_tab.b_active = 2; /* should now be 2 */ 478 upaddr->upba = um->um_ubinfo; 479 upaddr->upcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300); 480 } 481 482 /* 483 * Handle a disk interrupt. 484 */ 485 upintr(sc21) 486 register sc21; 487 { 488 register struct buf *bp, *dp; 489 register struct uba_ctlr *um = upminfo[sc21]; 490 register struct uba_device *ui; 491 register struct updevice *upaddr = (struct updevice *)um->um_addr; 492 register unit; 493 struct up_softc *sc = &up_softc[um->um_ctlr]; 494 int as = (upaddr->upas & 0377) | sc->sc_softas; 495 int needie = 1, waitdry; 496 497 sc->sc_wticks = 0; 498 sc->sc_softas = 0; 499 /* 500 * If controller wasn't transferring, then this is an 501 * interrupt for attention status on seeking drives. 502 * Just service them. 503 */ 504 if (um->um_tab.b_active != 2 && !sc->sc_recal) { 505 if (upaddr->upcs1 & UP_TRE) 506 upaddr->upcs1 = UP_TRE; 507 goto doattn; 508 } 509 um->um_tab.b_active = 1; 510 /* 511 * Get device and block structures, and a pointer 512 * to the uba_device for the drive. Select the drive. 513 */ 514 dp = um->um_tab.b_actf; 515 bp = dp->b_actf; 516 ui = updinfo[dkunit(bp)]; 517 dk_busy &= ~(1 << ui->ui_dk); 518 if ((upaddr->upcs2&07) != ui->ui_slave) 519 upaddr->upcs2 = ui->ui_slave; 520 if (bp->b_flags&B_BAD) { 521 if (upecc(ui, CONT)) 522 return; 523 } 524 /* 525 * Check for and process errors on 526 * either the drive or the controller. 527 */ 528 if ((upaddr->upds&UPDS_ERR) || (upaddr->upcs1&UP_TRE)) { 529 waitdry = 0; 530 while ((upaddr->upds & UPDS_DRY) == 0) { 531 if (++waitdry > 512) 532 break; 533 upwaitdry++; 534 } 535 if (upaddr->uper1&UPER1_WLE) { 536 /* 537 * Give up on write locked devices 538 * immediately. 539 */ 540 printf("up%d: write locked\n", dkunit(bp)); 541 bp->b_flags |= B_ERROR; 542 } else if (++um->um_tab.b_errcnt > 27) { 543 /* 544 * After 28 retries (16 without offset, and 545 * 12 with offset positioning) give up. 546 */ 547 hard: 548 harderr(bp, "up"); 549 printf("cn=%d tn=%d sn=%d cs2=%b er1=%b er2=%b\n", 550 upaddr->updc, ((upaddr->upda)>>8)&077, 551 (upaddr->upda)&037, 552 upaddr->upcs2, UPCS2_BITS, 553 upaddr->uper1, UPER1_BITS, 554 upaddr->uper2, UPER2_BITS); 555 bp->b_flags |= B_ERROR; 556 } else if (upaddr->uper2 & UPER2_BSE) { 557 if (upecc(ui, BSE)) 558 return; 559 else 560 goto hard; 561 } else { 562 /* 563 * Retriable error. 564 * If a soft ecc, correct it (continuing 565 * by returning if necessary. 566 * Otherwise fall through and retry the transfer 567 */ 568 if ((upaddr->uper1&(UPER1_DCK|UPER1_ECH))==UPER1_DCK) { 569 if (upecc(ui, ECC)) 570 return; 571 } else 572 um->um_tab.b_active = 0; /* force retry */ 573 } 574 /* 575 * Clear drive error and, every eight attempts, 576 * (starting with the fourth) 577 * recalibrate to clear the slate. 578 */ 579 upaddr->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO; 580 needie = 0; 581 if ((um->um_tab.b_errcnt&07) == 4 && um->um_tab.b_active == 0) { 582 upaddr->upcs1 = UP_RECAL|UP_IE|UP_GO; 583 sc->sc_recal = 0; 584 goto nextrecal; 585 } 586 } 587 /* 588 * Advance recalibration finite state machine 589 * if recalibrate in progress, through 590 * RECAL 591 * SEEK 592 * OFFSET (optional) 593 * RETRY 594 */ 595 switch (sc->sc_recal) { 596 597 case 1: 598 upaddr->updc = bp->b_cylin; 599 upaddr->upcs1 = UP_SEEK|UP_IE|UP_GO; 600 goto nextrecal; 601 case 2: 602 if (um->um_tab.b_errcnt < 16 || (bp->b_flags&B_READ) == 0) 603 goto donerecal; 604 upaddr->upof = up_offset[um->um_tab.b_errcnt & 017] | UPOF_FMT22; 605 upaddr->upcs1 = UP_IE|UP_OFFSET|UP_GO; 606 goto nextrecal; 607 nextrecal: 608 sc->sc_recal++; 609 um->um_tab.b_active = 1; 610 return; 611 donerecal: 612 case 3: 613 sc->sc_recal = 0; 614 um->um_tab.b_active = 0; 615 break; 616 } 617 /* 618 * If still ``active'', then don't need any more retries. 619 */ 620 if (um->um_tab.b_active) { 621 /* 622 * If we were offset positioning, 623 * return to centerline. 624 */ 625 if (um->um_tab.b_errcnt >= 16) { 626 upaddr->upof = UPOF_FMT22; 627 upaddr->upcs1 = UP_RTC|UP_GO|UP_IE; 628 while (upaddr->upds & UPDS_PIP) 629 DELAY(25); 630 needie = 0; 631 } 632 um->um_tab.b_active = 0; 633 um->um_tab.b_errcnt = 0; 634 um->um_tab.b_actf = dp->b_forw; 635 dp->b_active = 0; 636 dp->b_errcnt = 0; 637 dp->b_actf = bp->av_forw; 638 bp->b_resid = (-upaddr->upwc * sizeof(short)); 639 iodone(bp); 640 /* 641 * If this unit has more work to do, 642 * then start it up right away. 643 */ 644 if (dp->b_actf) 645 if (upustart(ui)) 646 needie = 0; 647 } 648 as &= ~(1<<ui->ui_slave); 649 /* 650 * Release unibus resources and flush data paths. 651 */ 652 ubadone(um); 653 doattn: 654 /* 655 * Process other units which need attention. 656 * For each unit which needs attention, call 657 * the unit start routine to place the slave 658 * on the controller device queue. 659 */ 660 while (unit = ffs(as)) { 661 unit--; /* was 1 origin */ 662 as &= ~(1<<unit); 663 upaddr->upas = 1<<unit; 664 if (unit < UPIPUNITS && upustart(upip[sc21][unit])) 665 needie = 0; 666 } 667 /* 668 * If the controller is not transferring, but 669 * there are devices ready to transfer, start 670 * the controller. 671 */ 672 if (um->um_tab.b_actf && um->um_tab.b_active == 0) 673 if (upstart(um)) 674 needie = 0; 675 if (needie) 676 upaddr->upcs1 = UP_IE; 677 } 678 679 upread(dev, uio) 680 dev_t dev; 681 struct uio *uio; 682 { 683 register int unit = minor(dev) >> 3; 684 685 if (unit >= NUP) 686 return (ENXIO); 687 return (physio(upstrategy, &rupbuf[unit], dev, B_READ, minphys, uio)); 688 } 689 690 upwrite(dev, uio) 691 dev_t dev; 692 struct uio *uio; 693 { 694 register int unit = minor(dev) >> 3; 695 696 if (unit >= NUP) 697 return (ENXIO); 698 return (physio(upstrategy, &rupbuf[unit], dev, B_WRITE, minphys, uio)); 699 } 700 701 /* 702 * Correct an ECC error, and restart the i/o to complete 703 * the transfer if necessary. This is quite complicated because 704 * the transfer may be going to an odd memory address base and/or 705 * across a page boundary. 706 */ 707 upecc(ui, flag) 708 register struct uba_device *ui; 709 int flag; 710 { 711 register struct updevice *up = (struct updevice *)ui->ui_addr; 712 register struct buf *bp = uputab[ui->ui_unit].b_actf; 713 register struct uba_ctlr *um = ui->ui_mi; 714 register struct upst *st; 715 struct uba_regs *ubp = ui->ui_hd->uh_uba; 716 register int i; 717 caddr_t addr; 718 int reg, bit, byte, npf, mask, o, cmd, ubaddr; 719 int bn, cn, tn, sn; 720 721 /* 722 * Npf is the number of sectors transferred before the sector 723 * containing the ECC error, and reg is the UBA register 724 * mapping (the first part of) the transfer. 725 * O is offset within a memory page of the first byte transferred. 726 */ 727 if (flag == CONT) 728 npf = bp->b_error; 729 else 730 npf = btop((up->upwc * sizeof(short)) + bp->b_bcount); 731 reg = btop(um->um_ubinfo&0x3ffff) + npf; 732 o = (int)bp->b_un.b_addr & PGOFSET; 733 mask = up->upec2; 734 #ifdef UPECCDEBUG 735 printf("npf %d reg %x o %d mask %o pos %d\n", npf, reg, o, mask, 736 up->upec1); 737 #endif 738 bn = dkblock(bp); 739 st = &upst[ui->ui_type]; 740 cn = bp->b_cylin; 741 sn = bn%st->nspc + npf; 742 tn = sn/st->nsect; 743 sn %= st->nsect; 744 cn += tn/st->ntrak; 745 tn %= st->ntrak; 746 ubapurge(um); 747 um->um_tab.b_active=2; 748 /* 749 * action taken depends on the flag 750 */ 751 switch(flag){ 752 case ECC: 753 npf--; 754 reg--; 755 mask = up->upec2; 756 printf("up%d%c: soft ecc sn%d\n", dkunit(bp), 757 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf); 758 /* 759 * Flush the buffered data path, and compute the 760 * byte and bit position of the error. The variable i 761 * is the byte offset in the transfer, the variable byte 762 * is the offset from a page boundary in main memory. 763 */ 764 i = up->upec1 - 1; /* -1 makes 0 origin */ 765 bit = i&07; 766 i = (i&~07)>>3; 767 byte = i + o; 768 /* 769 * Correct while possible bits remain of mask. Since mask 770 * contains 11 bits, we continue while the bit offset is > -11. 771 * Also watch out for end of this block and the end of the whole 772 * transfer. 773 */ 774 while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { 775 addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ 776 (byte & PGOFSET); 777 #ifdef UPECCDEBUG 778 printf("addr %x map reg %x\n", 779 addr, *(int *)(&ubp->uba_map[reg+btop(byte)])); 780 printf("old: %x, ", getmemc(addr)); 781 #endif 782 putmemc(addr, getmemc(addr)^(mask<<bit)); 783 #ifdef UPECCDEBUG 784 printf("new: %x\n", getmemc(addr)); 785 #endif 786 byte++; 787 i++; 788 bit -= 8; 789 } 790 if (up->upwc == 0) 791 return (0); 792 npf++; 793 reg++; 794 break; 795 case BSE: 796 /* 797 * if not in bad sector table, return 0 798 */ 799 if ((bn = isbad(&upbad[ui->ui_unit], cn, tn, sn)) < 0) 800 return(0); 801 /* 802 * flag this one as bad 803 */ 804 bp->b_flags |= B_BAD; 805 bp->b_error = npf + 1; 806 #ifdef UPECCDEBUG 807 printf("BSE: restart at %d\n",npf+1); 808 #endif 809 bn = st->ncyl * st->nspc -st->nsect - 1 - bn; 810 cn = bn / st->nspc; 811 sn = bn % st->nspc; 812 tn = sn / st->nsect; 813 sn %= st->nsect; 814 up->upwc = -(512 / sizeof (short)); 815 #ifdef UPECCDEBUG 816 printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); 817 #endif 818 break; 819 case CONT: 820 #ifdef UPECCDEBUG 821 printf("upecc, CONT: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn); 822 #endif 823 bp->b_flags &= ~B_BAD; 824 up->upwc = -((bp->b_bcount - (int)ptob(npf)) / sizeof(short)); 825 if (up->upwc == 0) 826 return(0); 827 break; 828 } 829 if (up->upwc == 0) { 830 um->um_tab.b_active = 0; 831 return (0); 832 } 833 /* 834 * Have to continue the transfer... clear the drive, 835 * and compute the position where the transfer is to continue. 836 * We have completed npf+1 sectors of the transfer already; 837 * restart at offset o of next sector (i.e. in UBA register reg+1). 838 */ 839 #ifdef notdef 840 up->uper1 = 0; 841 up->upcs1 |= UP_GO; 842 #else 843 up->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO; 844 up->updc = cn; 845 up->upda = (tn << 8) | sn; 846 ubaddr = (int)ptob(reg) + o; 847 up->upba = ubaddr; 848 cmd = (ubaddr >> 8) & 0x300; 849 cmd |= ((bp->b_flags&B_READ)?UP_RCOM:UP_WCOM)|UP_IE|UP_GO; 850 um->um_tab.b_errcnt = 0; 851 up->upcs1 = cmd; 852 #endif 853 return (1); 854 } 855 856 /* 857 * Reset driver after UBA init. 858 * Cancel software state of all pending transfers 859 * and restart all units and the controller. 860 */ 861 upreset(uban) 862 int uban; 863 { 864 register struct uba_ctlr *um; 865 register struct uba_device *ui; 866 register sc21, unit; 867 868 for (sc21 = 0; sc21 < NSC; sc21++) { 869 if ((um = upminfo[sc21]) == 0 || um->um_ubanum != uban || 870 um->um_alive == 0) 871 continue; 872 printf(" sc%d", sc21); 873 um->um_tab.b_active = 0; 874 um->um_tab.b_actf = um->um_tab.b_actl = 0; 875 up_softc[sc21].sc_recal = 0; 876 up_softc[sc21].sc_wticks = 0; 877 if (um->um_ubinfo) { 878 printf("<%d>", (um->um_ubinfo>>28)&0xf); 879 um->um_ubinfo = 0; 880 } 881 ((struct updevice *)(um->um_addr))->upcs2 = UPCS2_CLR; 882 for (unit = 0; unit < NUP; unit++) { 883 if ((ui = updinfo[unit]) == 0) 884 continue; 885 if (ui->ui_alive == 0 || ui->ui_mi != um) 886 continue; 887 uputab[unit].b_active = 0; 888 (void) upustart(ui); 889 } 890 (void) upstart(um); 891 } 892 } 893 894 /* 895 * Wake up every second and if an interrupt is pending 896 * but nothing has happened increment a counter. 897 * If nothing happens for 20 seconds, reset the UNIBUS 898 * and begin anew. 899 */ 900 upwatch() 901 { 902 register struct uba_ctlr *um; 903 register sc21, unit; 904 register struct up_softc *sc; 905 906 timeout(upwatch, (caddr_t)0, hz); 907 for (sc21 = 0; sc21 < NSC; sc21++) { 908 um = upminfo[sc21]; 909 if (um == 0 || um->um_alive == 0) 910 continue; 911 sc = &up_softc[sc21]; 912 if (um->um_tab.b_active == 0) { 913 for (unit = 0; unit < NUP; unit++) 914 if (uputab[unit].b_active && 915 updinfo[unit]->ui_mi == um) 916 goto active; 917 sc->sc_wticks = 0; 918 continue; 919 } 920 active: 921 sc->sc_wticks++; 922 if (sc->sc_wticks >= 20) { 923 sc->sc_wticks = 0; 924 printf("sc%d: lost interrupt\n", sc21); 925 ubareset(um->um_ubanum); 926 } 927 } 928 } 929 930 #define DBSIZE 20 931 932 updump(dev) 933 dev_t dev; 934 { 935 struct updevice *upaddr; 936 char *start; 937 int num, blk, unit; 938 struct size *sizes; 939 register struct uba_regs *uba; 940 register struct uba_device *ui; 941 register short *rp; 942 struct upst *st; 943 register int retry; 944 945 unit = minor(dev) >> 3; 946 if (unit >= NUP) 947 return (ENXIO); 948 #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) 949 ui = phys(struct uba_device *, updinfo[unit]); 950 if (ui->ui_alive == 0) 951 return (ENXIO); 952 uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; 953 ubainit(uba); 954 upaddr = (struct updevice *)ui->ui_physaddr; 955 DELAY(5000000); 956 num = maxfree; 957 upaddr->upcs2 = unit; 958 DELAY(100); 959 upaddr->upcs1 = UP_DCLR|UP_GO; 960 upaddr->upcs1 = UP_PRESET|UP_GO; 961 upaddr->upof = UPOF_FMT22; 962 retry = 0; 963 do { 964 DELAY(25); 965 if (++retry > 527) 966 break; 967 } while ((upaddr->upds & UP_RDY) == 0); 968 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) 969 return (EFAULT); 970 start = 0; 971 st = &upst[ui->ui_type]; 972 sizes = phys(struct size *, st->sizes); 973 if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) 974 return (EINVAL); 975 while (num > 0) { 976 register struct pte *io; 977 register int i; 978 int cn, sn, tn; 979 daddr_t bn; 980 981 blk = num > DBSIZE ? DBSIZE : num; 982 io = uba->uba_map; 983 for (i = 0; i < blk; i++) 984 *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV; 985 *(int *)io = 0; 986 bn = dumplo + btop(start); 987 cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; 988 sn = bn%st->nspc; 989 tn = sn/st->nsect; 990 sn = sn%st->nsect; 991 upaddr->updc = cn; 992 rp = (short *) &upaddr->upda; 993 *rp = (tn << 8) + sn; 994 *--rp = 0; 995 *--rp = -blk*NBPG / sizeof (short); 996 *--rp = UP_GO|UP_WCOM; 997 retry = 0; 998 do { 999 DELAY(25); 1000 if (++retry > 527) 1001 break; 1002 } while ((upaddr->upcs1 & UP_RDY) == 0); 1003 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { 1004 printf("up%d: not ready", unit); 1005 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { 1006 printf("\n"); 1007 return (EIO); 1008 } 1009 printf(" (flakey)\n"); 1010 } 1011 if (upaddr->upds&UPDS_ERR) 1012 return (EIO); 1013 start += blk*NBPG; 1014 num -= blk; 1015 } 1016 return (0); 1017 } 1018 #endif 1019