X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/89bd2f016f32d202ff42a7604bc98499c0d3cd53..de59ccc2375aad4c9f0ff41f3291584ead755f15:/usr/src/sys/vax/uba/up.c diff --git a/usr/src/sys/vax/uba/up.c b/usr/src/sys/vax/uba/up.c index bdc6524545..44e1bdbeb2 100644 --- a/usr/src/sys/vax/uba/up.c +++ b/usr/src/sys/vax/uba/up.c @@ -1,4 +1,4 @@ -/* up.c 4.30 81/03/07 */ +/* up.c 4.53 82/05/27 */ #include "up.h" #if NSC > 0 @@ -6,13 +6,9 @@ * UNIBUS disk driver with overlapped seeks and ECC recovery. * * TODO: - * Add reading of bad sector information and disk layout from sector 1 * Add bad sector forwarding code - * Check multiple drive handling - * Check unibus reset code - * Check that offset recovery code, etc works + * Check that offset recovery code works */ -#define DELAY(N) { register int d; d = N; while (--d > 0); } #include "../h/param.h" #include "../h/systm.h" @@ -46,13 +42,22 @@ struct size daddr_t nblocks; int cyloff; } up_sizes[8] = { +#ifdef ERNIE + 49324, 0, /* A=cyl 0 thru 26 */ +#else 15884, 0, /* A=cyl 0 thru 26 */ +#endif 33440, 27, /* B=cyl 27 thru 81 */ 495520, 0, /* C=cyl 0 thru 814 */ 15884, 562, /* D=cyl 562 thru 588 */ 55936, 589, /* E=cyl 589 thru 680 */ - 81472, 681, /* F=cyl 681 thru 814 */ - 153824, 562, /* G=cyl 562 thru 814 */ +#ifndef NOBADSECT + 81376, 681, /* F=cyl 681 thru 814 */ + 153728, 562, /* G=cyl 562 thru 814 */ +#else + 81472, 681, + 153824, 562, +#endif 291346, 82, /* H=cyl 82 thru 561 */ }, fj_sizes[8] = { 15884, 0, /* A=cyl 0 thru 49 */ @@ -62,11 +67,28 @@ struct size 0, 0, 0, 0, 0, 0, - 213760, 155, /* H=cyl 155 thru 822 */ +#ifndef NOBADSECT + 213664, 155, /* H=cyl 155 thru 822 */ +#else + 213760, 155, +#endif +}, upam_sizes[8] = { + 15884, 0, /* A=cyl 0 thru 31 */ + 33440, 32, /* B=cyl 32 thru 97 */ + 524288, 0, /* C=cyl 0 thru 1023 */ + 27786, 668, + 27786, 723, + 125440, 778, + 181760, 668, /* G=cyl 668 thru 1022 */ + 291346, 98, /* H=cyl 98 thru 667 */ }; /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ -#define _upSDIST 2 /* 1.0 msec */ +/* + * On a 780 upSDIST could be 2, but + * in the interest of 750's... + */ +#define _upSDIST 3 /* 1.5 msec */ #define _upRDIST 4 /* 2.0 msec */ int upSDIST = _upSDIST; @@ -75,7 +97,8 @@ int upRDIST = _upRDIST; int upprobe(), upslave(), upattach(), updgo(), upintr(); struct uba_ctlr *upminfo[NSC]; struct uba_device *updinfo[NUP]; -struct uba_device *upip[NSC][4]; +#define UPIPUNITS 8 +struct uba_device *upip[NSC][UPIPUNITS]; /* fuji w/fixed head gives n,n+4 */ u_short upstd[] = { 0776700, 0774400, 0776300, 0 }; struct uba_driver scdriver = @@ -92,11 +115,14 @@ struct upst { 32, 19, 32*19, 823, up_sizes, /* 9300/cdc */ /* 9300 actually has 815 cylinders... */ 32, 10, 32*10, 823, fj_sizes, /* fujitsu 160m */ + 32, 16, 32*16, 1024, upam_sizes, /* ampex capricorn */ }; u_char up_offset[16] = { - UP_P400, UP_M400, UP_P400, UP_M400, UP_P800, UP_M800, UP_P800, UP_M800, - UP_P1200, UP_M1200, UP_P1200, UP_M1200, 0, 0, 0, 0 + UPOF_P400, UPOF_M400, UPOF_P400, UPOF_M400, + UPOF_P800, UPOF_M800, UPOF_P800, UPOF_M800, + UPOF_P1200, UPOF_M1200, UPOF_P1200, UPOF_M1200, + 0, 0, 0, 0 }; struct buf rupbuf[NUP]; @@ -134,7 +160,8 @@ upslave(ui, reg) upaddr->upcs1 = 0; /* conservative */ upaddr->upcs2 = ui->ui_slave; - if (upaddr->upcs2&UP_NED) { + upaddr->upcs1 = UP_NOP|UP_GO; + if (upaddr->upcs2&UPCS2_NED) { upaddr->upcs1 = UP_DCLR|UP_GO; return (0); } @@ -144,9 +171,7 @@ upslave(ui, reg) upattach(ui) register struct uba_device *ui; { -#ifdef notdef register struct updevice *upaddr; -#endif if (upwstart == 0) { timeout(upwatch, (caddr_t)0, hz); @@ -156,15 +181,23 @@ upattach(ui) dk_mspw[ui->ui_dk] = .0000020345; upip[ui->ui_ctlr][ui->ui_slave] = ui; up_softc[ui->ui_ctlr].sc_ndrive++; -#ifdef notdef upaddr = (struct updevice *)ui->ui_addr; upaddr->upcs1 = 0; upaddr->upcs2 = ui->ui_slave; - upaddr->uphr = -1; - /* ... */ - if (upaddr-> ... == 10) - ui->ui_type = 1; -#endif + upaddr->uphr = UPHR_MAXTRAK; + if (upaddr->uphr == 9) + ui->ui_type = 1; /* fujitsu hack */ + else if (upaddr->uphr == 15) + ui->ui_type = 2; /* ampex hack */ + upaddr->upcs2 = UPCS2_CLR; +/* + upaddr->uphr = UPHR_MAXCYL; + printf("maxcyl %d\n", upaddr->uphr); + upaddr->uphr = UPHR_MAXTRAK; + printf("maxtrak %d\n", upaddr->uphr); + upaddr->uphr = UPHR_MAXSECT; + printf("maxsect %d\n", upaddr->uphr); +*/ } upstrategy(bp) @@ -265,17 +298,17 @@ upustart(ui) * If drive has just come up, * setup the pack. */ - if ((upaddr->upds & UP_VV) == 0) { + if ((upaddr->upds & UPDS_VV) == 0) { /* SHOULD WARN SYSTEM THAT THIS HAPPENED */ upaddr->upcs1 = UP_IE|UP_DCLR|UP_GO; upaddr->upcs1 = UP_IE|UP_PRESET|UP_GO; - upaddr->upof = UP_FMT22; + upaddr->upof = UPOF_FMT22; didie = 1; } /* * If drive is offline, forget about positioning. */ - if ((upaddr->upds & (UP_DPR|UP_MOL)) != (UP_DPR|UP_MOL)) + if ((upaddr->upds & (UPDS_DPR|UPDS_MOL)) != (UPDS_DPR|UPDS_MOL)) goto done; /* * If there is only one drive, @@ -385,14 +418,14 @@ loop: * Check that it is ready and online */ waitdry = 0; - while ((upaddr->upds&UP_DRY) == 0) { + while ((upaddr->upds&UPDS_DRY) == 0) { if (++waitdry > 512) break; upwaitdry++; } - if ((upaddr->upds & UP_DREADY) != UP_DREADY) { + if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { printf("up%d: not ready", dkunit(bp)); - if ((upaddr->upds & UP_DREADY) != UP_DREADY) { + if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { printf("\n"); um->um_tab.b_active = 0; um->um_tab.b_errcnt = 0; @@ -408,15 +441,6 @@ loop: */ printf(" (flakey)\n"); } - /* - * After 16th retry, do offset positioning - */ - if (um->um_tab.b_errcnt >= 16 && (bp->b_flags&B_READ) != 0) { - upaddr->upof = up_offset[um->um_tab.b_errcnt & 017] | UP_FMT22; - upaddr->upcs1 = UP_IE|UP_OFFSET|UP_GO; - while (upaddr->upds & UP_PIP) - DELAY(25); - } /* * Setup for the transfer, and get in the * UNIBUS adaptor queue. @@ -429,7 +453,7 @@ loop: else cmd = UP_IE|UP_WCOM|UP_GO; um->um_cmd = cmd; - ubago(ui); + (void) ubago(ui); return (1); } @@ -441,6 +465,7 @@ updgo(um) { register struct updevice *upaddr = (struct updevice *)um->um_addr; + um->um_tab.b_active = 2; /* should now be 2 */ upaddr->upba = um->um_ubinfo; upaddr->upcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300); } @@ -467,11 +492,12 @@ upintr(sc21) * interrupt for attention status on seeking drives. * Just service them. */ - if (um->um_tab.b_active == 0) { + if (um->um_tab.b_active != 2 && !sc->sc_recal) { if (upaddr->upcs1 & UP_TRE) upaddr->upcs1 = UP_TRE; goto doattn; } + um->um_tab.b_active = 1; /* * Get device and block structures, and a pointer * to the uba_device for the drive. Select the drive. @@ -486,14 +512,14 @@ upintr(sc21) * Check for and process errors on * either the drive or the controller. */ - if ((upaddr->upds&UP_ERR) || (upaddr->upcs1&UP_TRE)) { + if ((upaddr->upds&UPDS_ERR) || (upaddr->upcs1&UP_TRE)) { waitdry = 0; - while ((upaddr->upds & UP_DRY) == 0) { + while ((upaddr->upds & UPDS_DRY) == 0) { if (++waitdry > 512) break; upwaitdry++; } - if (upaddr->uper1&UP_WLE) { + if (upaddr->uper1&UPER1_WLE) { /* * Give up on write locked devices * immediately. @@ -519,7 +545,7 @@ upintr(sc21) * Otherwise fall through and retry the transfer */ um->um_tab.b_active = 0; /* force retry */ - if ((upaddr->uper1&(UP_DCK|UP_ECH))==UP_DCK) + if ((upaddr->uper1&(UPER1_DCK|UPER1_ECH))==UPER1_DCK) if (upecc(ui)) return; } @@ -530,23 +556,41 @@ upintr(sc21) */ upaddr->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO; needie = 0; - if ((um->um_tab.b_errcnt&07) == 4) { + if ((um->um_tab.b_errcnt&07) == 4 && um->um_tab.b_active == 0) { upaddr->upcs1 = UP_RECAL|UP_IE|UP_GO; - um->um_tab.b_active = 1; - sc->sc_recal = 1; - return; + sc->sc_recal = 0; + goto nextrecal; } } /* - * Done retrying transfer... release - * resources... if we were recalibrating, - * then retry the transfer. - * Mathematical note: 28%8 != 4. + * Advance recalibration finite state machine + * if recalibrate in progress, through + * RECAL + * SEEK + * OFFSET (optional) + * RETRY */ - ubadone(um); - if (sc->sc_recal) { + switch (sc->sc_recal) { + + case 1: + upaddr->updc = bp->b_cylin; + upaddr->upcs1 = UP_SEEK|UP_IE|UP_GO; + goto nextrecal; + case 2: + if (um->um_tab.b_errcnt < 16 || (bp->b_flags&B_READ) == 0) + goto donerecal; + upaddr->upof = up_offset[um->um_tab.b_errcnt & 017] | UPOF_FMT22; + upaddr->upcs1 = UP_IE|UP_OFFSET|UP_GO; + goto nextrecal; + nextrecal: + sc->sc_recal++; + um->um_tab.b_active = 1; + return; + donerecal: + case 3: sc->sc_recal = 0; - um->um_tab.b_active = 0; /* force retry */ + um->um_tab.b_active = 0; + break; } /* * If still ``active'', then don't need any more retries. @@ -557,9 +601,9 @@ upintr(sc21) * return to centerline. */ if (um->um_tab.b_errcnt >= 16) { - upaddr->upof = UP_FMT22; + upaddr->upof = UPOF_FMT22; upaddr->upcs1 = UP_RTC|UP_GO|UP_IE; - while (upaddr->upds & UP_PIP) + while (upaddr->upds & UPDS_PIP) DELAY(25); needie = 0; } @@ -580,6 +624,10 @@ upintr(sc21) needie = 0; } as &= ~(1<ui_slave); + /* + * Release unibus resources and flush data paths. + */ + ubadone(um); doattn: /* * Process other units which need attention. @@ -587,12 +635,13 @@ doattn: * the unit start routine to place the slave * on the controller device queue. */ - for (unit = 0; as; as >>= 1, unit++) - if (as & 1) { - upaddr->upas = 1<upas = 1<b_dev)&07), bp->b_blkno + npf); mask = up->upec2; +#ifdef UPECCDEBUG + printf("npf %d reg %x o %d mask %o pos %d\n", npf, reg, o, mask, + up->upec1); +#endif /* * Flush the buffered data path, and compute the * byte and bit position of the error. The variable i @@ -678,12 +731,19 @@ upecc(ui) while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ (byte & PGOFSET); +#ifdef UPECCDEBUG + printf("addr %x map reg %x\n", + addr, *(int *)(&ubp->uba_map[reg+btop(byte)])); + printf("old: %x, ", getmemc(addr)); +#endif putmemc(addr, getmemc(addr)^(mask<um_tab.b_active++; /* Either complete or continuing... */ if (up->upwc == 0) return (0); /* @@ -711,6 +771,7 @@ upecc(ui) up->upba = ubaddr; cmd = (ubaddr >> 8) & 0x300; cmd |= UP_IE|UP_GO|UP_RCOM; + um->um_tab.b_active = 2; /* continuing transfer ... */ up->upcs1 = cmd; #endif return (1); @@ -736,11 +797,12 @@ upreset(uban) um->um_tab.b_active = 0; um->um_tab.b_actf = um->um_tab.b_actl = 0; up_softc[sc21].sc_recal = 0; + up_softc[sc21].sc_wticks = 0; if (um->um_ubinfo) { printf("<%d>", (um->um_ubinfo>>28)&0xf); ubadone(um); } - ((struct updevice *)(um->um_addr))->upcs2 = UP_CLR; + ((struct updevice *)(um->um_addr))->upcs2 = UPCS2_CLR; for (unit = 0; unit < NUP; unit++) { if ((ui = updinfo[unit]) == 0) continue; @@ -796,12 +858,13 @@ updump(dev) { struct updevice *upaddr; char *start; - int num, blk, unit, i; + int num, blk, unit; struct size *sizes; register struct uba_regs *uba; register struct uba_device *ui; register short *rp; struct upst *st; + register int retry; unit = minor(dev) >> 3; if (unit >= NUP) @@ -813,20 +876,22 @@ updump(dev) uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; ubainit(uba); upaddr = (struct updevice *)ui->ui_physaddr; - DELAY(2000000); + DELAY(5000000); num = maxfree; - start = 0; upaddr->upcs2 = unit; DELAY(100); - if ((upaddr->upcs1&UP_DVA) == 0) - return (EFAULT); - if ((upaddr->upds & UP_VV) == 0) { - upaddr->upcs1 = UP_DCLR|UP_GO; - upaddr->upcs1 = UP_PRESET|UP_GO; - upaddr->upof = UP_FMT22; - } - if ((upaddr->upds & UP_DREADY) != UP_DREADY) + upaddr->upcs1 = UP_DCLR|UP_GO; + upaddr->upcs1 = UP_PRESET|UP_GO; + upaddr->upof = UPOF_FMT22; + retry = 0; + do { + DELAY(25); + if (++retry > 527) + break; + } while ((upaddr->upds & UP_RDY) == 0); + if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) return (EFAULT); + start = 0; st = &upst[ui->ui_type]; sizes = phys(struct size *, st->sizes); if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) @@ -853,10 +918,21 @@ updump(dev) *--rp = 0; *--rp = -blk*NBPG / sizeof (short); *--rp = UP_GO|UP_WCOM; + retry = 0; do { DELAY(25); + if (++retry > 527) + break; } while ((upaddr->upcs1 & UP_RDY) == 0); - if (upaddr->upcs1&UP_ERR) + if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { + printf("up%d: not ready", unit); + if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { + printf("\n"); + return (EIO); + } + printf(" (flakey)\n"); + } + if (upaddr->upds&UPDS_ERR) return (EIO); start += blk*NBPG; num -= blk;