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