From: Tom London Date: Tue, 23 Jan 1979 10:56:26 +0000 (-0500) Subject: Bell 32V development X-Git-Tag: Bell-32V~289 X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/commitdiff_plain/cbc918de217d6541b483f3a496b9c8bdf4e15b2c Bell 32V development Work on file usr/src/slowsys/sys/hp.c Co-Authored-By: John Reiser Synthesized-from: 32v --- diff --git a/usr/src/slowsys/sys/hp.c b/usr/src/slowsys/sys/hp.c new file mode 100644 index 0000000000..f8c87ffeaf --- /dev/null +++ b/usr/src/slowsys/sys/hp.c @@ -0,0 +1,327 @@ +/* + * RP04/RP06 disk driver + */ + +#include "../h/param.h" +#include "../h/uba.h" +#include "../h/systm.h" +#include "../h/buf.h" +#include "../h/conf.h" +#include "../h/dir.h" +#include "../h/user.h" +#include "../h/map.h" +#include "../h/mba.h" + +#define DK_N 0 + +struct device +{ + int hpcs1; /* control and Status register 1 */ + int hpds; /* Drive Status */ + int hper1; /* Error register 1 */ + int hpmr; /* Maintenance */ + int hpas; /* Attention Summary */ + int hpda; /* Desired address register */ + int hpdt; /* Drive type */ + int hpla; /* Look ahead */ + int hpsn; /* serial number */ + int hpof; /* Offset register */ + int hpdc; /* Desired Cylinder address register */ + int hpcc; /* Current Cylinder */ + int hper2; /* Error register 2 */ + int hper3; /* Error register 3 */ + int hpec1; /* Burst error bit position */ + int hpec2; /* Burst error bit pattern */ +}; + +#define HPADDR ((struct device *)(MBA0 + MBA_ERB)) +#define NHP 1 +#define NSECT 22 +#define NTRAC 19 +#define SDIST 2 +#define RDIST 6 + +struct size +{ + daddr_t nblocks; + int cyloff; +} hp_sizes[8] = +{ + 9614, 0, /* cyl 0 thru 23 */ + 65536, 44, /* cyl 44 thru 200 */ + 65536, 201, /* cyl 201 thru 514 */ + 65536, 515, /* cyl 515 thru 671 */ + 65536, 358, /* cyl 358 thru 407 */ + 0, 0, + 328548, 25, /* cyl 25 thru 810 */ + 322278, 44, /* cyl 44 thru 717 */ +}; + +#define P400 020 +#define M400 0220 +#define P800 040 +#define M800 0240 +#define P1200 060 +#define M1200 0260 +int hp_offset[16] = +{ + P400, M400, P400, M400, + P800, M800, P800, M800, + P1200, M1200, P1200, M1200, + 0, 0, 0, 0, +}; + +struct buf hptab; +struct buf rhpbuf; +struct buf hputab[NHP]; + +#define GO 01 +#define PRESET 020 +#define RTC 016 +#define OFFSET 014 +#define SEARCH 030 +#define RECAL 06 +#define DCLR 010 +#define WCOM 060 +#define RCOM 070 + +#define IE 0100 +#define PIP 020000 +#define DRY 0200 +#define ERR 040000 +#define TRE 040000 +#define DCK 0100000 +#define WLE 04000 +#define ECH 0100 +#define VV 0100 +#define DPR 0400 +#define MOL 010000 +#define FMT22 010000 + +#define b_cylin b_resid + +daddr_t dkblock(); + +hpstrategy(bp) +register struct buf *bp; +{ + register struct buf *dp; + register unit; + long sz, bn; + + unit = minor(bp->b_dev) & 077; + sz = bp->b_bcount; + sz = (sz+511) >> 9; + if (unit >= (NHP<<3) || + bp->b_blkno < 0 || + (bn = dkblock(bp))+sz > hp_sizes[unit&07].nblocks) { + bp->b_flags |= B_ERROR; + iodone(bp); + return; + } + bp->b_cylin = bn/(NSECT*NTRAC) + hp_sizes[unit&07].cyloff; + unit = dkunit(bp); + dp = &hputab[unit]; + spl5(); + disksort(dp, bp); + if (dp->b_active == 0) { + hpustart(unit); + if(hptab.b_active == 0) + hpstart(); + } + spl0(); +} + +hpustart(unit) +register unit; +{ + register struct buf *bp, *dp; + register struct device *hpaddr; + daddr_t bn; + int sn, cn, csn; + + ((struct mba_regs *)MBA0)->mba_cr |= MBAIE; + HPADDR->hpas = 1<= NHP) + return; + dk_busy &= ~(1<<(unit+DK_N)); + dp = &hputab[unit]; + if((bp=dp->b_actf) == NULL) + return; + hpaddr = (struct device *)((int *)HPADDR + 32*unit); + if((hpaddr->hpds & VV) == 0) { + hpaddr->hpcs1 = PRESET|GO; + hpaddr->hpof = FMT22; + } + if(dp->b_active) + goto done; + dp->b_active++; + if ((hpaddr->hpds & (DPR|MOL)) != (DPR|MOL)) + goto done; + + bn = dkblock(bp); + cn = bp->b_cylin; + sn = bn%(NSECT*NTRAC); + sn = (sn+NSECT-SDIST)%NSECT; + + if((hpaddr->hpcc & 0xffff) != cn) + goto search; + csn = ((hpaddr->hpla & 0xffff)>>6) - sn + SDIST - 1; + if(csn < 0) + csn += NSECT; + if(csn > NSECT-RDIST) + goto done; + +search: + hpaddr->hpdc = cn; + hpaddr->hpda = sn; + hpaddr->hpcs1 = SEARCH|GO; + unit += DK_N; + dk_busy |= 1<b_forw = NULL; + if(hptab.b_actf == NULL) + hptab.b_actf = dp; else + hptab.b_actl->b_forw = dp; + hptab.b_actl = dp; +} + +hpstart() +{ + register struct buf *bp, *dp; + register unit; + register struct device *hpaddr; + daddr_t bn; + int dn, sn, tn, cn; + +loop: + if ((dp = hptab.b_actf) == NULL) + return; + if ((bp = dp->b_actf) == NULL) { + hptab.b_actf = dp->b_forw; + goto loop; + } + hptab.b_active++; + unit = minor(bp->b_dev) & 077; + dn = dkunit(bp); + bn = dkblock(bp); + cn = bn/(NSECT*NTRAC) + hp_sizes[unit&07].cyloff; + sn = bn%(NSECT*NTRAC); + tn = sn/NSECT; + sn = sn%NSECT; + + hpaddr = (struct device *)((int *)HPADDR + 32*dn); + if ((hpaddr->hpds & (DPR|MOL)) != (DPR|MOL)) { + hptab.b_active = 0; + hptab.b_errcnt = 0; + dp->b_actf = bp->av_forw; + bp->b_flags |= B_ERROR; + iodone(bp); + goto loop; + } + if(hptab.b_errcnt >= 16) { + hpaddr->hpof = hp_offset[hptab.b_errcnt & 017] | FMT22; + ((struct mba_regs *)MBA0)->mba_cr &= ~MBAIE; + hpaddr->hpcs1 = OFFSET|GO; + while(hpaddr->hpds & PIP) + ; + ((struct mba_regs *)MBA0)->mba_cr |= MBAIE; + } + hpaddr->hpdc = cn; + hpaddr->hpda = (tn << 8) + sn; + mbastart(bp, hpaddr); + + dk_busy |= 1<<(DK_N+NHP); + dk_numb[DK_N+NHP] += 1; + unit = bp->b_bcount>>6; + dk_wds[DK_N+NHP] += unit; +} + +hpintr(mbastat, as) +{ + register struct buf *bp, *dp; + register unit; + register struct device *hpaddr; + int i, j; + + if(hptab.b_active) { + dk_busy &= ~(1<<(DK_N+NHP)); + dp = hptab.b_actf; + bp = dp->b_actf; + unit = dkunit(bp); + hpaddr = (struct device *)((int *)HPADDR + 32*unit); + if (hpaddr->hpds & ERR || mbastat & MBAEBITS) { /* error bit */ + while((hpaddr->hpds & DRY) == 0) + ; + if(++hptab.b_errcnt > 28 || hpaddr->hper1&WLE) + bp->b_flags |= B_ERROR; else + hptab.b_active = 0; + if(hptab.b_errcnt > 27) + deverror(bp, mbastat, hpaddr->hper1); + if((bp->b_flags&B_PHYS) == 0 && + (hpaddr->hper1 & (DCK|ECH)) == DCK) { + i = (hpaddr->hpec1 & 0xffff) - 1; + j = i&037; + i =>> 5; + if(i >= 0 && i <128) { + bp->b_un.b_words[i] =^ (hpaddr->hpec2 & 0xffff) << j; + bp->b_un.b_words[i+1] =^ (hpaddr->hpec2 & 0xffff) >> (32-j); + } + hptab.b_active++; + printf("%D ", bp->b_blkno); + prdev("ECC", bp->b_dev); + } + hpaddr->hpcs1 = DCLR|GO; + if((hptab.b_errcnt&07) == 4) { + ((struct mba_regs *)MBA0)->mba_cr &= ~MBAIE; + hpaddr->hpcs1 = RECAL|GO; + while(hpaddr->hpds & PIP) + ; + ((struct mba_regs *)MBA0)->mba_cr |= MBAIE; + } + } + if(hptab.b_active) { + if(hptab.b_errcnt) { + ((struct mba_regs *)MBA0)->mba_cr &= ~MBAIE; + hpaddr->hpcs1 = RTC|GO; + while(hpaddr->hpds & PIP) + ; + ((struct mba_regs *)MBA0)->mba_cr |= MBAIE; + } + hptab.b_active = 0; + hptab.b_errcnt = 0; + hptab.b_actf = dp->b_forw; + dp->b_active = 0; + dp->b_errcnt = 0; + dp->b_actf = bp->av_forw; + bp->b_resid = -(((struct mba_regs *)MBA0)->mba_bcr) & 0xffff; + iodone(bp); + if(dp->b_actf) + hpustart(unit); + } + as &= ~(1<mba_cr |= MBAIE; + } + for(unit=0; unit