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