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