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