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