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