1 /* up.c 4.75 83/05/30 */ 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 addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ 803 (byte & PGOFSET); 804 #ifdef UPECCDEBUG 805 printf("addr %x map reg %x\n", 806 addr, *(int *)(&ubp->uba_map[reg+btop(byte)])); 807 printf("old: %x, ", getmemc(addr)); 808 #endif 809 putmemc(addr, getmemc(addr)^(mask<<bit)); 810 #ifdef UPECCDEBUG 811 printf("new: %x\n", getmemc(addr)); 812 #endif 813 byte++; 814 i++; 815 bit -= 8; 816 } 817 if (up->upwc == 0) 818 return (0); 819 npf++; 820 reg++; 821 break; 822 case BSE: 823 /* 824 * if not in bad sector table, return 0 825 */ 826 if ((bn = isbad(&upbad[ui->ui_unit], cn, tn, sn)) < 0) 827 return(0); 828 /* 829 * flag this one as bad 830 */ 831 bp->b_flags |= B_BAD; 832 bp->b_error = npf + 1; 833 #ifdef UPECCDEBUG 834 printf("BSE: restart at %d\n",npf+1); 835 #endif 836 bn = st->ncyl * st->nspc -st->nsect - 1 - bn; 837 cn = bn / st->nspc; 838 sn = bn % st->nspc; 839 tn = sn / st->nsect; 840 sn %= st->nsect; 841 up->upwc = -(512 / sizeof (short)); 842 #ifdef UPECCDEBUG 843 printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); 844 #endif 845 break; 846 case CONT: 847 #ifdef UPECCDEBUG 848 printf("upecc, CONT: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn); 849 #endif 850 bp->b_flags &= ~B_BAD; 851 up->upwc = -((bp->b_bcount - (int)ptob(npf)) / sizeof(short)); 852 if (up->upwc == 0) 853 return(0); 854 break; 855 } 856 if (up->upwc == 0) { 857 um->um_tab.b_active = 0; 858 return (0); 859 } 860 /* 861 * Have to continue the transfer... clear the drive, 862 * and compute the position where the transfer is to continue. 863 * We have completed npf+1 sectors of the transfer already; 864 * restart at offset o of next sector (i.e. in UBA register reg+1). 865 */ 866 #ifdef notdef 867 up->uper1 = 0; 868 up->upcs1 |= UP_GO; 869 #else 870 up->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO; 871 up->updc = cn; 872 up->upda = (tn << 8) | sn; 873 ubaddr = (int)ptob(reg) + o; 874 up->upba = ubaddr; 875 cmd = (ubaddr >> 8) & 0x300; 876 cmd |= ((bp->b_flags&B_READ)?UP_RCOM:UP_WCOM)|UP_IE|UP_GO; 877 um->um_tab.b_errcnt = 0; 878 up->upcs1 = cmd; 879 #endif 880 return (1); 881 } 882 883 /* 884 * Reset driver after UBA init. 885 * Cancel software state of all pending transfers 886 * and restart all units and the controller. 887 */ 888 upreset(uban) 889 int uban; 890 { 891 register struct uba_ctlr *um; 892 register struct uba_device *ui; 893 register sc21, unit; 894 895 for (sc21 = 0; sc21 < NSC; sc21++) { 896 if ((um = upminfo[sc21]) == 0 || um->um_ubanum != uban || 897 um->um_alive == 0) 898 continue; 899 printf(" sc%d", sc21); 900 um->um_tab.b_active = 0; 901 um->um_tab.b_actf = um->um_tab.b_actl = 0; 902 up_softc[sc21].sc_recal = 0; 903 up_softc[sc21].sc_wticks = 0; 904 if (um->um_ubinfo) { 905 printf("<%d>", (um->um_ubinfo>>28)&0xf); 906 um->um_ubinfo = 0; 907 } 908 ((struct updevice *)(um->um_addr))->upcs2 = UPCS2_CLR; 909 for (unit = 0; unit < NUP; unit++) { 910 if ((ui = updinfo[unit]) == 0) 911 continue; 912 if (ui->ui_alive == 0 || ui->ui_mi != um) 913 continue; 914 uputab[unit].b_active = 0; 915 (void) upustart(ui); 916 } 917 (void) upstart(um); 918 } 919 } 920 921 /* 922 * Wake up every second and if an interrupt is pending 923 * but nothing has happened increment a counter. 924 * If nothing happens for 20 seconds, reset the UNIBUS 925 * and begin anew. 926 */ 927 upwatch() 928 { 929 register struct uba_ctlr *um; 930 register sc21, unit; 931 register struct up_softc *sc; 932 933 timeout(upwatch, (caddr_t)0, hz); 934 for (sc21 = 0; sc21 < NSC; sc21++) { 935 um = upminfo[sc21]; 936 if (um == 0 || um->um_alive == 0) 937 continue; 938 sc = &up_softc[sc21]; 939 if (um->um_tab.b_active == 0) { 940 for (unit = 0; unit < NUP; unit++) 941 if (uputab[unit].b_active && 942 updinfo[unit]->ui_mi == um) 943 goto active; 944 sc->sc_wticks = 0; 945 continue; 946 } 947 active: 948 sc->sc_wticks++; 949 if (sc->sc_wticks >= 20) { 950 sc->sc_wticks = 0; 951 printf("sc%d: lost interrupt\n", sc21); 952 ubareset(um->um_ubanum); 953 } 954 } 955 } 956 957 #define DBSIZE 20 958 959 updump(dev) 960 dev_t dev; 961 { 962 struct updevice *upaddr; 963 char *start; 964 int num, blk, unit; 965 struct size *sizes; 966 register struct uba_regs *uba; 967 register struct uba_device *ui; 968 register short *rp; 969 struct upst *st; 970 register int retry; 971 972 unit = minor(dev) >> 3; 973 if (unit >= NUP) 974 return (ENXIO); 975 #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) 976 ui = phys(struct uba_device *, updinfo[unit]); 977 if (ui->ui_alive == 0) 978 return (ENXIO); 979 uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; 980 ubainit(uba); 981 upaddr = (struct updevice *)ui->ui_physaddr; 982 DELAY(5000000); 983 num = maxfree; 984 upaddr->upcs2 = unit; 985 DELAY(100); 986 upaddr->upcs1 = UP_DCLR|UP_GO; 987 upaddr->upcs1 = UP_PRESET|UP_GO; 988 upaddr->upof = UPOF_FMT22; 989 retry = 0; 990 do { 991 DELAY(25); 992 if (++retry > 527) 993 break; 994 } while ((upaddr->upds & UP_RDY) == 0); 995 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) 996 return (EFAULT); 997 start = 0; 998 st = &upst[ui->ui_type]; 999 sizes = phys(struct size *, st->sizes); 1000 if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) 1001 return (EINVAL); 1002 while (num > 0) { 1003 register struct pte *io; 1004 register int i; 1005 int cn, sn, tn; 1006 daddr_t bn; 1007 1008 blk = num > DBSIZE ? DBSIZE : num; 1009 io = uba->uba_map; 1010 for (i = 0; i < blk; i++) 1011 *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV; 1012 *(int *)io = 0; 1013 bn = dumplo + btop(start); 1014 cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; 1015 sn = bn%st->nspc; 1016 tn = sn/st->nsect; 1017 sn = sn%st->nsect; 1018 upaddr->updc = cn; 1019 rp = (short *) &upaddr->upda; 1020 *rp = (tn << 8) + sn; 1021 *--rp = 0; 1022 *--rp = -blk*NBPG / sizeof (short); 1023 *--rp = UP_GO|UP_WCOM; 1024 retry = 0; 1025 do { 1026 DELAY(25); 1027 if (++retry > 527) 1028 break; 1029 } while ((upaddr->upcs1 & UP_RDY) == 0); 1030 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { 1031 printf("up%d: not ready", unit); 1032 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { 1033 printf("\n"); 1034 return (EIO); 1035 } 1036 printf(" (flakey)\n"); 1037 } 1038 if (upaddr->upds&UPDS_ERR) 1039 return (EIO); 1040 start += blk*NBPG; 1041 num -= blk; 1042 } 1043 return (0); 1044 } 1045 1046 upsize(dev) 1047 dev_t dev; 1048 { 1049 int unit = minor(dev) >> 3; 1050 struct uba_device *ui; 1051 struct upst *st; 1052 1053 if (unit >= NUP || (ui = updinfo[unit]) == 0 || ui->ui_alive == 0) 1054 return (-1); 1055 st = &upst[ui->ui_type]; 1056 return (st->sizes[minor(dev) & 07].nblocks); 1057 } 1058 #endif 1059