1 /* up.c 4.52 82/05/19 */ 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 if (++waitdry > 512) 423 break; 424 upwaitdry++; 425 } 426 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { 427 printf("up%d: not ready", dkunit(bp)); 428 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { 429 printf("\n"); 430 um->um_tab.b_active = 0; 431 um->um_tab.b_errcnt = 0; 432 dp->b_actf = bp->av_forw; 433 dp->b_active = 0; 434 bp->b_flags |= B_ERROR; 435 iodone(bp); 436 goto loop; 437 } 438 /* 439 * Oh, well, sometimes this 440 * happens, for reasons unknown. 441 */ 442 printf(" (flakey)\n"); 443 } 444 /* 445 * Setup for the transfer, and get in the 446 * UNIBUS adaptor queue. 447 */ 448 upaddr->updc = bp->b_cylin; 449 upaddr->upda = (tn << 8) + sn; 450 upaddr->upwc = -bp->b_bcount / sizeof (short); 451 if (bp->b_flags & B_READ) 452 cmd = UP_IE|UP_RCOM|UP_GO; 453 else 454 cmd = UP_IE|UP_WCOM|UP_GO; 455 um->um_cmd = cmd; 456 (void) ubago(ui); 457 return (1); 458 } 459 460 /* 461 * Now all ready to go, stuff the registers. 462 */ 463 updgo(um) 464 struct uba_ctlr *um; 465 { 466 register struct updevice *upaddr = (struct updevice *)um->um_addr; 467 468 um->um_tab.b_active++; /* should now be 2 */ 469 upaddr->upba = um->um_ubinfo; 470 upaddr->upcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300); 471 } 472 473 /* 474 * Handle a disk interrupt. 475 */ 476 upintr(sc21) 477 register sc21; 478 { 479 register struct buf *bp, *dp; 480 register struct uba_ctlr *um = upminfo[sc21]; 481 register struct uba_device *ui; 482 register struct updevice *upaddr = (struct updevice *)um->um_addr; 483 register unit; 484 struct up_softc *sc = &up_softc[um->um_ctlr]; 485 int as = (upaddr->upas & 0377) | sc->sc_softas; 486 int needie = 1, waitdry; 487 488 sc->sc_wticks = 0; 489 sc->sc_softas = 0; 490 /* 491 * If controller wasn't transferring, then this is an 492 * interrupt for attention status on seeking drives. 493 * Just service them. 494 */ 495 if (um->um_tab.b_active != 2 && !sc->sc_recal) { 496 if (upaddr->upcs1 & UP_TRE) 497 upaddr->upcs1 = UP_TRE; 498 goto doattn; 499 } 500 /* 501 * Get device and block structures, and a pointer 502 * to the uba_device for the drive. Select the drive. 503 */ 504 dp = um->um_tab.b_actf; 505 bp = dp->b_actf; 506 ui = updinfo[dkunit(bp)]; 507 dk_busy &= ~(1 << ui->ui_dk); 508 if ((upaddr->upcs2&07) != ui->ui_slave) 509 upaddr->upcs2 = ui->ui_slave; 510 /* 511 * Check for and process errors on 512 * either the drive or the controller. 513 */ 514 if ((upaddr->upds&UPDS_ERR) || (upaddr->upcs1&UP_TRE)) { 515 waitdry = 0; 516 while ((upaddr->upds & UPDS_DRY) == 0) { 517 if (++waitdry > 512) 518 break; 519 upwaitdry++; 520 } 521 if (upaddr->uper1&UPER1_WLE) { 522 /* 523 * Give up on write locked devices 524 * immediately. 525 */ 526 printf("up%d: write locked\n", dkunit(bp)); 527 bp->b_flags |= B_ERROR; 528 } else if (++um->um_tab.b_errcnt > 27) { 529 /* 530 * After 28 retries (16 without offset, and 531 * 12 with offset positioning) give up. 532 */ 533 harderr(bp, "up"); 534 printf("cs2=%b er1=%b er2=%b\n", 535 upaddr->upcs2, UPCS2_BITS, 536 upaddr->uper1, UPER1_BITS, 537 upaddr->uper2, UPER2_BITS); 538 bp->b_flags |= B_ERROR; 539 } else { 540 /* 541 * Retriable error. 542 * If a soft ecc, correct it (continuing 543 * by returning if necessary. 544 * Otherwise fall through and retry the transfer 545 */ 546 um->um_tab.b_active = 0; /* force retry */ 547 if ((upaddr->uper1&(UPER1_DCK|UPER1_ECH))==UPER1_DCK) 548 if (upecc(ui)) 549 return; 550 } 551 /* 552 * Clear drive error and, every eight attempts, 553 * (starting with the fourth) 554 * recalibrate to clear the slate. 555 */ 556 upaddr->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO; 557 needie = 0; 558 if ((um->um_tab.b_errcnt&07) == 4 && um->um_tab.b_active == 0) { 559 upaddr->upcs1 = UP_RECAL|UP_IE|UP_GO; 560 sc->sc_recal = 0; 561 goto nextrecal; 562 } 563 } 564 /* 565 * Advance recalibration finite state machine 566 * if recalibrate in progress, through 567 * RECAL 568 * SEEK 569 * OFFSET (optional) 570 * RETRY 571 */ 572 switch (sc->sc_recal) { 573 574 case 1: 575 upaddr->updc = bp->b_cylin; 576 upaddr->upcs1 = UP_SEEK|UP_IE|UP_GO; 577 goto nextrecal; 578 case 2: 579 if (um->um_tab.b_errcnt < 16 || (bp->b_flags&B_READ) == 0) 580 goto donerecal; 581 upaddr->upof = up_offset[um->um_tab.b_errcnt & 017] | UPOF_FMT22; 582 upaddr->upcs1 = UP_IE|UP_OFFSET|UP_GO; 583 goto nextrecal; 584 nextrecal: 585 sc->sc_recal++; 586 um->um_tab.b_active = 1; 587 return; 588 donerecal: 589 case 3: 590 sc->sc_recal = 0; 591 um->um_tab.b_active = 0; 592 break; 593 } 594 /* 595 * If still ``active'', then don't need any more retries. 596 */ 597 if (um->um_tab.b_active) { 598 /* 599 * If we were offset positioning, 600 * return to centerline. 601 */ 602 if (um->um_tab.b_errcnt >= 16) { 603 upaddr->upof = UPOF_FMT22; 604 upaddr->upcs1 = UP_RTC|UP_GO|UP_IE; 605 while (upaddr->upds & UPDS_PIP) 606 DELAY(25); 607 needie = 0; 608 } 609 um->um_tab.b_active = 0; 610 um->um_tab.b_errcnt = 0; 611 um->um_tab.b_actf = dp->b_forw; 612 dp->b_active = 0; 613 dp->b_errcnt = 0; 614 dp->b_actf = bp->av_forw; 615 bp->b_resid = (-upaddr->upwc * sizeof(short)); 616 iodone(bp); 617 /* 618 * If this unit has more work to do, 619 * then start it up right away. 620 */ 621 if (dp->b_actf) 622 if (upustart(ui)) 623 needie = 0; 624 } 625 as &= ~(1<<ui->ui_slave); 626 /* 627 * Release unibus resources and flush data paths. 628 */ 629 ubadone(um); 630 doattn: 631 /* 632 * Process other units which need attention. 633 * For each unit which needs attention, call 634 * the unit start routine to place the slave 635 * on the controller device queue. 636 */ 637 while (unit = ffs(as)) { 638 unit--; /* was 1 origin */ 639 as &= ~(1<<unit); 640 upaddr->upas = 1<<unit; 641 if (unit < UPIPUNITS && upustart(upip[sc21][unit])) 642 needie = 0; 643 } 644 /* 645 * If the controller is not transferring, but 646 * there are devices ready to transfer, start 647 * the controller. 648 */ 649 if (um->um_tab.b_actf && um->um_tab.b_active == 0) 650 if (upstart(um)) 651 needie = 0; 652 if (needie) 653 upaddr->upcs1 = UP_IE; 654 } 655 656 upread(dev) 657 dev_t dev; 658 { 659 register int unit = minor(dev) >> 3; 660 661 if (unit >= NUP) 662 u.u_error = ENXIO; 663 else 664 physio(upstrategy, &rupbuf[unit], dev, B_READ, minphys); 665 } 666 667 upwrite(dev) 668 dev_t dev; 669 { 670 register int unit = minor(dev) >> 3; 671 672 if (unit >= NUP) 673 u.u_error = ENXIO; 674 else 675 physio(upstrategy, &rupbuf[unit], dev, B_WRITE, minphys); 676 } 677 678 /* 679 * Correct an ECC error, and restart the i/o to complete 680 * the transfer if necessary. This is quite complicated because 681 * the transfer may be going to an odd memory address base and/or 682 * across a page boundary. 683 */ 684 upecc(ui) 685 register struct uba_device *ui; 686 { 687 register struct updevice *up = (struct updevice *)ui->ui_addr; 688 register struct buf *bp = uputab[ui->ui_unit].b_actf; 689 register struct uba_ctlr *um = ui->ui_mi; 690 register struct upst *st; 691 struct uba_regs *ubp = ui->ui_hd->uh_uba; 692 register int i; 693 caddr_t addr; 694 int reg, bit, byte, npf, mask, o, cmd, ubaddr; 695 int bn, cn, tn, sn; 696 697 /* 698 * Npf is the number of sectors transferred before the sector 699 * containing the ECC error, and reg is the UBA register 700 * mapping (the first part of) the transfer. 701 * O is offset within a memory page of the first byte transferred. 702 */ 703 npf = btop((up->upwc * sizeof(short)) + bp->b_bcount) - 1; 704 reg = btop(um->um_ubinfo&0x3ffff) + npf; 705 o = (int)bp->b_un.b_addr & PGOFSET; 706 printf("up%d%c: soft ecc sn%d\n", dkunit(bp), 707 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf); 708 mask = up->upec2; 709 #ifdef UPECCDEBUG 710 printf("npf %d reg %x o %d mask %o pos %d\n", npf, reg, o, mask, 711 up->upec1); 712 #endif 713 /* 714 * Flush the buffered data path, and compute the 715 * byte and bit position of the error. The variable i 716 * is the byte offset in the transfer, the variable byte 717 * is the offset from a page boundary in main memory. 718 */ 719 ubapurge(um); 720 i = up->upec1 - 1; /* -1 makes 0 origin */ 721 bit = i&07; 722 i = (i&~07)>>3; 723 byte = i + o; 724 /* 725 * Correct while possible bits remain of mask. Since mask 726 * contains 11 bits, we continue while the bit offset is > -11. 727 * Also watch out for end of this block and the end of the whole 728 * transfer. 729 */ 730 while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { 731 addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ 732 (byte & PGOFSET); 733 #ifdef UPECCDEBUG 734 printf("addr %x map reg %x\n", 735 addr, *(int *)(&ubp->uba_map[reg+btop(byte)])); 736 printf("old: %x, ", getmemc(addr)); 737 #endif 738 putmemc(addr, getmemc(addr)^(mask<<bit)); 739 #ifdef UPECCDEBUG 740 printf("new: %x\n", getmemc(addr)); 741 #endif 742 byte++; 743 i++; 744 bit -= 8; 745 } 746 um->um_tab.b_active = 2; /* Either complete or continuing... */ 747 if (up->upwc == 0) 748 return (0); 749 /* 750 * Have to continue the transfer... clear the drive, 751 * and compute the position where the transfer is to continue. 752 * We have completed npf+1 sectors of the transfer already; 753 * restart at offset o of next sector (i.e. in UBA register reg+1). 754 */ 755 #ifdef notdef 756 up->uper1 = 0; 757 up->upcs1 |= UP_GO; 758 #else 759 up->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO; 760 bn = dkblock(bp); 761 st = &upst[ui->ui_type]; 762 cn = bp->b_cylin; 763 sn = bn%st->nspc + npf + 1; 764 tn = sn/st->nsect; 765 sn %= st->nsect; 766 cn += tn/st->ntrak; 767 tn %= st->ntrak; 768 up->updc = cn; 769 up->upda = (tn << 8) | sn; 770 ubaddr = (int)ptob(reg+1) + o; 771 up->upba = ubaddr; 772 cmd = (ubaddr >> 8) & 0x300; 773 cmd |= UP_IE|UP_GO|UP_RCOM; 774 up->upcs1 = cmd; 775 #endif 776 return (1); 777 } 778 779 /* 780 * Reset driver after UBA init. 781 * Cancel software state of all pending transfers 782 * and restart all units and the controller. 783 */ 784 upreset(uban) 785 int uban; 786 { 787 register struct uba_ctlr *um; 788 register struct uba_device *ui; 789 register sc21, unit; 790 791 for (sc21 = 0; sc21 < NSC; sc21++) { 792 if ((um = upminfo[sc21]) == 0 || um->um_ubanum != uban || 793 um->um_alive == 0) 794 continue; 795 printf(" sc%d", sc21); 796 um->um_tab.b_active = 0; 797 um->um_tab.b_actf = um->um_tab.b_actl = 0; 798 up_softc[sc21].sc_recal = 0; 799 up_softc[sc21].sc_wticks = 0; 800 if (um->um_ubinfo) { 801 printf("<%d>", (um->um_ubinfo>>28)&0xf); 802 ubadone(um); 803 } 804 ((struct updevice *)(um->um_addr))->upcs2 = UPCS2_CLR; 805 for (unit = 0; unit < NUP; unit++) { 806 if ((ui = updinfo[unit]) == 0) 807 continue; 808 if (ui->ui_alive == 0 || ui->ui_mi != um) 809 continue; 810 uputab[unit].b_active = 0; 811 (void) upustart(ui); 812 } 813 (void) upstart(um); 814 } 815 } 816 817 /* 818 * Wake up every second and if an interrupt is pending 819 * but nothing has happened increment a counter. 820 * If nothing happens for 20 seconds, reset the UNIBUS 821 * and begin anew. 822 */ 823 upwatch() 824 { 825 register struct uba_ctlr *um; 826 register sc21, unit; 827 register struct up_softc *sc; 828 829 timeout(upwatch, (caddr_t)0, hz); 830 for (sc21 = 0; sc21 < NSC; sc21++) { 831 um = upminfo[sc21]; 832 if (um == 0 || um->um_alive == 0) 833 continue; 834 sc = &up_softc[sc21]; 835 if (um->um_tab.b_active == 0) { 836 for (unit = 0; unit < NUP; unit++) 837 if (uputab[unit].b_active && 838 updinfo[unit]->ui_mi == um) 839 goto active; 840 sc->sc_wticks = 0; 841 continue; 842 } 843 active: 844 sc->sc_wticks++; 845 if (sc->sc_wticks >= 20) { 846 sc->sc_wticks = 0; 847 printf("sc%d: lost interrupt\n", sc21); 848 ubareset(um->um_ubanum); 849 } 850 } 851 } 852 853 #define DBSIZE 20 854 855 updump(dev) 856 dev_t dev; 857 { 858 struct updevice *upaddr; 859 char *start; 860 int num, blk, unit; 861 struct size *sizes; 862 register struct uba_regs *uba; 863 register struct uba_device *ui; 864 register short *rp; 865 struct upst *st; 866 register int retry; 867 868 unit = minor(dev) >> 3; 869 if (unit >= NUP) 870 return (ENXIO); 871 #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) 872 ui = phys(struct uba_device *, updinfo[unit]); 873 if (ui->ui_alive == 0) 874 return (ENXIO); 875 uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; 876 ubainit(uba); 877 upaddr = (struct updevice *)ui->ui_physaddr; 878 DELAY(5000000); 879 num = maxfree; 880 upaddr->upcs2 = unit; 881 DELAY(100); 882 upaddr->upcs1 = UP_DCLR|UP_GO; 883 upaddr->upcs1 = UP_PRESET|UP_GO; 884 upaddr->upof = UPOF_FMT22; 885 retry = 0; 886 do { 887 DELAY(25); 888 if (++retry > 527) 889 break; 890 } while ((upaddr->upds & UP_RDY) == 0); 891 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) 892 return (EFAULT); 893 start = 0; 894 st = &upst[ui->ui_type]; 895 sizes = phys(struct size *, st->sizes); 896 if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) 897 return (EINVAL); 898 while (num > 0) { 899 register struct pte *io; 900 register int i; 901 int cn, sn, tn; 902 daddr_t bn; 903 904 blk = num > DBSIZE ? DBSIZE : num; 905 io = uba->uba_map; 906 for (i = 0; i < blk; i++) 907 *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV; 908 *(int *)io = 0; 909 bn = dumplo + btop(start); 910 cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; 911 sn = bn%st->nspc; 912 tn = sn/st->nsect; 913 sn = sn%st->nsect; 914 upaddr->updc = cn; 915 rp = (short *) &upaddr->upda; 916 *rp = (tn << 8) + sn; 917 *--rp = 0; 918 *--rp = -blk*NBPG / sizeof (short); 919 *--rp = UP_GO|UP_WCOM; 920 retry = 0; 921 do { 922 DELAY(25); 923 if (++retry > 527) 924 break; 925 } while ((upaddr->upcs1 & UP_RDY) == 0); 926 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { 927 printf("up%d: not ready", unit); 928 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { 929 printf("\n"); 930 return (EIO); 931 } 932 printf(" (flakey)\n"); 933 } 934 if (upaddr->upds&UPDS_ERR) 935 return (EIO); 936 start += blk*NBPG; 937 num -= blk; 938 } 939 return (0); 940 } 941 #endif 942