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