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