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