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