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