X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/3ac0c79cf895abd1b67b5eb61e27d15c77f96932..b28deaf8866c3aba2ee330e5166bf1abf68c5c87:/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 c3b5008c15..fe6fed6a7f 100644 --- a/usr/src/sys/vax/uba/up.c +++ b/usr/src/sys/vax/uba/up.c @@ -1,33 +1,14 @@ -/* up.c 3.27 %G% */ +/* up.c 4.10 %G% */ -#include "../conf/up.h" +#include "up.h" +#if NUP > 0 +#if SC11 > 0 +#include "../dev/up.c.SC11" +#else /* * UNIBUS disk driver with overlapped seeks and ECC recovery. - * - * This driver works marginally on an Emulex SC-11B controller with rev - * level J microcode, defining: - * int olducode = 1; - * to force CPU stalling delays. - * - * It has worked with no delays and no problems on a prototype - * SC-21 controller. Emulex intends to upgrade all SC-11s on VAXes to SC-21s. - * You should get a SC-21 to replace any SC-11 on a VAX. - * - * SC-11B Controller switch settings: - * SW1-1 5/19 surfaces (off, 19 surfaces on Ampex 9300) - * SW1-2 chksum enable (off, checksum disabled) - * SW1-3 volume select (off, 815 cylinders) - * SW1-4 sector select (on, 32 sectors) - * SW1-5 unused (off) - * SW1-6 port select (on, single port) - * SW1-7 npr delay (off, disable) - * SW1-8 ecc test mode (off, disable) - * and top mounted switches: - * SW2-1 extend opcodes (off=open, disable) - * SW2-2 extend diag (off=open, disable) - * SW2-3 4 wd dma burst (on=closed, enable) - * SW2-4 unused (off=open) */ +#define DELAY(N) { register int d; d = N; while (--d > 0); } #include "../h/param.h" #include "../h/systm.h" @@ -95,8 +76,8 @@ int upseek; * and in the driver then we take it as it is. Otherwise we do a SEARCH * requesting an interrupt upSDIST sectors in advance. */ -#define _upSDIST 3 /* 1.5 msec */ -#define _upRDIST 6 /* 3.0 msec */ +#define _upSDIST 2 /* 1.0 msec */ +#define _upRDIST 4 /* 2.0 msec */ int upSDIST = _upSDIST; int upRDIST = _upRDIST; @@ -109,6 +90,9 @@ int upRDIST = _upRDIST; * On systems with RP06'es, we normally use only 291346 blocks of the H * area, and use DEF or G to cover the rest of the drive. The C system * covers the whole drive and can be used for pack-pack copying. + * + * Note: sizes here are for AMPEX drives with 815 cylinders. + * CDC drives can make the F,G, and H areas larger as they have 823 cylinders. */ struct size { @@ -122,8 +106,6 @@ struct size 55936, 589, /* E=cyl 589 thru 680 */ 81472, 681, /* F=cyl 681 thru 814 */ 153824, 562, /* G=cyl 562 thru 814 */ - 445664, 82, /* H=cyl 82 thru 814 */ -/* Later, and more safely for H area... 291346, 82, /* H=cyl 82 thru 561 */ }; @@ -133,7 +115,7 @@ struct size * +/- microinches. Note that header compare inhibit (HCI) is not * tried (this makes sense only during read, in any case.) * - * NOT ALL OF THESE ARE IMPLEMENTED ON 9300!?! + * NB: Not all drives/controllers emulate all of these. */ #define P400 020 #define M400 0220 @@ -193,6 +175,9 @@ struct buf rupbuf; /* Buffer for raw i/o */ /* Bits of upcs2 */ #define CLR 040 /* Controller clear */ +#define MXF 01000 +#define NEM 04000 + /* Bits of uper1 */ #define DCK 0100000 /* Ecc error occurred */ #define ECH 0100 /* Ecc error was unrecoverable */ @@ -204,24 +189,6 @@ struct buf rupbuf; /* Buffer for raw i/o */ #define b_cylin b_resid int up_ubinfo; /* Information about UBA usage saved here */ -/* - * The EMULEX controller balks if accessed quickly after - * certain operations. With rev J delays seem to be needed only - * when selecting a new unit, and in drive initialization type - * like PRESET and DCLR. The following variables control the delay - * DELAY(n) is approximately n usec. - */ -int olducode = 1; -int idelay = 500; /* Delay after PRESET or DCLR */ -int osdelay = 150; /* Old delay after selecting drive in upcs2 */ -int ordelay = 100; /* Old delay after SEARCH */ -int oasdel = 100; /* Old delay after clearing bit in upas */ -int nsdelay = 25; - -#define DELAY(N) { register int d; d = N; while (--d > 0); } - -int nwaitcs2; /* How many sdelay loops ? */ -int neasycs2; /* How many sdelay loops not needed ? */ int up_wticks; /* Ticks waiting for interrupt */ int upwstart; /* Have started guardian */ @@ -247,7 +214,7 @@ register struct buf *bp; long sz, bn; if (upwstart == 0) { - timeout((caddr_t)upwatch, 0, HZ); + timeout(upwatch, (caddr_t)0, HZ); upwstart++; } xunit = minor(bp->b_dev) & 077; @@ -261,8 +228,8 @@ register struct buf *bp; iodone(bp); return; } - if (DK_N+unit <= DK_NMAX) - dk_mspw[DK_N+unit] = .0000020345; + if (UPDK_N+unit <= UPDK_NMAX) + dk_mspw[UPDK_N+unit] = .0000020345; bp->b_cylin = bn/(NSECT*NTRAC) + up_sizes[xunit&07].cyloff; dp = &uputab[unit]; (void) spl5(); @@ -293,12 +260,9 @@ register unit; * Other drivers tend to say something like * upaddr->upcs1 = IE; * upaddr->upas = 1<= NUP) goto out; - if (unit+DK_N <= DK_NMAX) - dk_busy &= ~(1<<(unit+DK_N)); + if (unit+UPDK_N <= UPDK_NMAX) + dk_busy &= ~(1<<(unit+UPDK_N)); dp = &uputab[unit]; if ((bp = dp->b_actf) == NULL) goto out; /* - * The SC-11B doesn't start SEARCH commands when transfers are - * in progress. In fact, it tends to get confused when given + * Most controllers don't start SEARCH commands when transfers are + * in progress. In fact, some tend to get confused when given * SEARCH'es during transfers, generating interrupts with neither * RDY nor a bit in the upas register. Thus we defer * until an interrupt when a transfer is pending. @@ -327,12 +291,8 @@ register unit; if (dp->b_active) goto done; dp->b_active = 1; - if ((upaddr->upcs2 & 07) != unit) { + if ((upaddr->upcs2 & 07) != unit) upaddr->upcs2 = unit; - DELAY(olducode ? osdelay : nsdelay); - nwaitcs2++; - } else - neasycs2++; /* * If we have changed packs or just initialized, * then the volume will not be valid; if so, clear @@ -340,9 +300,7 @@ register unit; */ if ((upaddr->upds & VV) == 0) { upaddr->upcs1 = IE|DCLR|GO; - DELAY(idelay); upaddr->upcs1 = IE|PRESET|GO; - DELAY(idelay); upaddr->upof = FMT22; didie = 1; } @@ -383,13 +341,11 @@ search: /* * Mark this unit busy. */ - unit += DK_N; - if (unit <= DK_NMAX) { + unit += UPDK_N; + if (unit <= UPDK_NMAX) { dk_busy |= 1<upcs2 & 07) != dn) { + if ((upaddr->upcs2 & 07) != dn) upaddr->upcs2 = dn; - /* DELAY(sdelay); Provided by ubasetup() */ - nwaitcs2++; - } else - neasycs2++; - up_ubinfo = ubasetup(bp, 1); /* Providing delay */ + up_ubinfo = ubasetup(bp, 1); /* * If drive is not present and on-line, then * get rid of this with an error and loop to get @@ -472,7 +424,7 @@ loop: bp->b_flags |= B_ERROR; iodone(bp); /* A funny place to do this ... */ - ubafree(up_ubinfo), up_ubinfo = 0; + ubarelse(&up_ubinfo); goto loop; } printf("-- came back\n"); @@ -484,7 +436,6 @@ loop: if (uptab.b_errcnt >= 16 && (bp->b_flags&B_WRITE) == 0) { upaddr->upof = up_offset[uptab.b_errcnt & 017] | FMT22; upaddr->upcs1 = IE|OFFSET|GO; - DELAY(idelay); while (upaddr->upds & PIP) DELAY(25); } @@ -505,13 +456,13 @@ loop: upaddr->upcs1 = cmd; /* * This is a controller busy situation. - * Record in dk slot NUP+DK_N (after last drive) + * Record in dk slot NUP+UPDK_N (after last drive) * unless there aren't that many slots reserved for * us in which case we record this as a drive busy * (if there is room for that). */ - unit = dn+DK_N; - if (unit <= DK_NMAX) { + unit = dn+UPDK_N; + if (unit <= UPDK_NMAX) { dk_busy |= 1<b_bcount>>6; @@ -558,15 +509,12 @@ upintr() dp = uptab.b_actf; bp = dp->b_actf; unit = dkunit(bp); - if (DK_N+unit <= DK_NMAX) - dk_busy &= ~(1<<(DK_N+unit)); - if ((upaddr->upcs2 & 07) != unit) { + if (UPDK_N+unit <= UPDK_NMAX) + dk_busy &= ~(1<<(UPDK_N+unit)); + if ((upaddr->upcs2 & 07) != unit) upaddr->upcs2 = unit; - DELAY(olducode ? osdelay : nsdelay); - nwaitcs2++; - } else - neasycs2++; if ((upaddr->upds&ERR) || (upaddr->upcs1&TRE)) { + int cs2; /* * An error occurred, indeed. Select this unit * to get at the drive status (a SEARCH may have @@ -588,7 +536,9 @@ upintr() else uptab.b_active = 0; /* To force retry */ if (uptab.b_errcnt > 27) - deverror(bp, upaddr->upcs2, upaddr->uper1); + cs2 = (int)upaddr->upcs2; + deverror(bp, (int)upaddr->upcs2, + (int)upaddr->uper1); /* * If this was a correctible ECC error, let upecc * do the dirty work to correct it. If upecc @@ -604,14 +554,17 @@ upintr() * to hopefully help clear up seek positioning problems. */ upaddr->upcs1 = TRE|IE|DCLR|GO; - DELAY(idelay); needie = 0; if ((uptab.b_errcnt&07) == 4) { upaddr->upcs1 = RECAL|GO|IE; - DELAY(idelay); while(upaddr->upds & PIP) DELAY(25); } + if (uptab.b_errcnt == 28 && cs2&(NEM|MXF)) { + printf("FLAKEY UP "); + ubareset(); + return; + } } /* * If we are still noted as active, then no @@ -625,7 +578,6 @@ upintr() if (uptab.b_active) { if (uptab.b_errcnt >= 16) { upaddr->upcs1 = RTC|GO|IE; - DELAY(idelay); while (upaddr->upds & PIP) DELAY(25); needie = 0; @@ -648,12 +600,10 @@ upintr() } as &= ~(1<upcs1 & TRE) { + if (upaddr->upcs1 & TRE) upaddr->upcs1 = TRE; - DELAY(idelay); - } } /* * If we have a unit with an outstanding SEARCH, @@ -667,18 +617,14 @@ upintr() upsoftas = 0; for (unit = 0; unit < NUP; unit++) if ((as|oupsoftas) & (1<upas = 1<upcs1 = IE; } @@ -725,7 +671,6 @@ register struct buf *bp; mask = up->upec2; if (mask == 0) { up->upof = FMT22; /* == RTC ???? */ - DELAY(idelay); return (0); } /* @@ -763,7 +708,6 @@ register struct buf *bp; * restart at offset o of next sector (i.e. in UBA register reg+1). */ up->upcs1 = TRE|IE|DCLR|GO; - DELAY(idelay); bn = dkblock(bp); cn = bp->b_cylin; sn = bn%(NSECT*NTRAC) + npf + 1; @@ -791,14 +735,14 @@ upreset() int unit; printf(" up"); + DELAY(15000000); /* give it time to self-test */ uptab.b_active = 0; uptab.b_actf = uptab.b_actl = 0; if (up_ubinfo) { printf("<%d>", (up_ubinfo>>28)&0xf); - ubafree(up_ubinfo), up_ubinfo = 0; + ubarelse(&up_ubinfo); } UPADDR->upcs2 = CLR; /* clear controller */ - DELAY(idelay); for (unit = 0; unit < NUP; unit++) { uputab[unit].b_active = 0; (void) upustart(unit); @@ -816,7 +760,7 @@ upwatch() { int i; - timeout((caddr_t)upwatch, 0, HZ); + timeout(upwatch, (caddr_t)0, HZ); if (uptab.b_active == 0) { for (i = 0; i < NUP; i++) if (uputab[i].b_active) @@ -833,3 +777,5 @@ active: printf("\n"); } } +#endif +#endif