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