home *** CD-ROM | disk | FTP | other *** search
- /*
- * RP04/RP06 disk driver
- */
-
- #include "../h/param.h"
- #include "../h/systm.h"
- #include "../h/buf.h"
- #include "../h/conf.h"
- #include "../h/dir.h"
- #include "../h/user.h"
-
- #define DK_N 0
-
- struct device
- {
- union {
- int w;
- char c[2];
- } hpcs1; /* Control and Status register 1 */
- int hpwc; /* Word count register */
- caddr_t hpba; /* UNIBUS address register */
- int hpda; /* Desired address register */
- union {
- int w;
- char c[2];
- } hpcs2; /* Control and Status register 2*/
- int hpds; /* Drive Status */
- int hper1; /* Error register 1 */
- int hpas; /* Attention Summary */
- int hpla; /* Look ahead */
- int hpdb; /* Data buffer */
- int hpmr; /* Maintenance register */
- int hpdt; /* Drive type */
- 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 */
- int hpbae; /* 11/70 bus extension */
- int hpcs3;
- };
-
- #define HPADDR ((struct device *)0176700)
- #define NHP 2
- #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 22 */
- 8778, 23, /* cyl 23 thru 43 */
- 0, 0,
- 0, 0,
- 161348, 44, /* cyl 44 thru 429 */
- 160930, 430, /* cyl 430 thru 814 */
- 153406, 44, /* cyl 44 thru 410 (rp04, rp05) */
- 322278, 44, /* cyl 44 thru 814 (rp06) */
- };
-
- #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;
- daddr_t bn;
- int sn, cn, csn;
-
- HPADDR->hpcs2.w = unit;
- HPADDR->hpcs1.c[0] = IE;
- HPADDR->hpas = 1<<unit;
-
- if(unit >= NHP)
- return;
- dk_busy &= ~(1<<(unit+DK_N));
- dp = &hputab[unit];
- if((bp=dp->b_actf) == NULL)
- return;
- if((HPADDR->hpds & VV) == 0) {
- HPADDR->hpcs1.c[0] = IE|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 != cn)
- goto search;
- csn = (HPADDR->hpla>>6) - sn + SDIST - 1;
- if(csn < 0)
- csn += NSECT;
- if(csn > NSECT-RDIST)
- goto done;
-
- search:
- HPADDR->hpdc = cn;
- HPADDR->hpda = sn;
- HPADDR->hpcs1.c[0] = IE|SEARCH|GO;
- unit += DK_N;
- dk_busy |= 1<<unit;
- dk_numb[unit] += 1;
- return;
-
- done:
- dp->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;
- 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->hpcs2.w = 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;
- HPADDR->hpcs1.w = OFFSET|GO;
- while(HPADDR->hpds & PIP)
- ;
- }
- HPADDR->hpdc = cn;
- HPADDR->hpda = (tn << 8) + sn;
- HPADDR->hpba = bp->b_un.b_addr;
- if(cputype == 70)
- HPADDR->hpbae = bp->b_xmem;
- HPADDR->hpwc = -(bp->b_bcount>>1);
- unit = ((bp->b_xmem&3) << 8) | IE | GO;
- if(bp->b_flags & B_READ)
- unit |= RCOM; else
- unit |= WCOM;
- HPADDR->hpcs1.w = unit;
-
- dk_busy |= 1<<(DK_N+NHP);
- dk_numb[DK_N+NHP] += 1;
- unit = bp->b_bcount>>6;
- dk_wds[DK_N+NHP] += unit;
- }
-
- hpintr()
- {
- register struct buf *bp, *dp;
- register unit;
- int as, i, j;
-
- as = HPADDR->hpas & 0377;
- if(hptab.b_active) {
- dk_busy &= ~(1<<(DK_N+NHP));
- dp = hptab.b_actf;
- bp = dp->b_actf;
- unit = dkunit(bp);
- HPADDR->hpcs2.c[0] = unit;
- if (HPADDR->hpcs1.w & TRE) { /* 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, HPADDR->hpcs2.w, HPADDR->hper1);
- if((bp->b_flags&B_PHYS) == 0 &&
- (HPADDR->hper1 & (DCK|ECH)) == DCK) {
- i = HPADDR->hpec1 - 1;
- j = i&017;
- i >>= 4;
- if(i >= 0 && i <256) {
- bp->b_un.b_words[i] ^= HPADDR->hpec2 << j;
- bp->b_un.b_words[i+1] ^= HPADDR->hpec2 >> (16-j);
- }
- hptab.b_active++;
- printf("%D ", bp->b_blkno);
- prdev("ECC", bp->b_dev);
- }
- HPADDR->hpcs1.w = TRE|IE|DCLR|GO;
- if((hptab.b_errcnt&07) == 4) {
- HPADDR->hpcs1.w = RECAL|IE|GO;
- while(HPADDR->hpds & PIP)
- ;
- }
- }
- if(hptab.b_active) {
- if(hptab.b_errcnt) {
- HPADDR->hpcs1.w = RTC|GO;
- while(HPADDR->hpds & PIP)
- ;
- }
- 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 = -(HPADDR->hpwc<<1);
- iodone(bp);
- HPADDR->hpcs1.w = IE;
- if(dp->b_actf)
- hpustart(unit);
- }
- as &= ~(1<<unit);
- } else {
- if(as == 0)
- HPADDR->hpcs1.w = IE;
- HPADDR->hpcs1.c[1] = TRE>>8;
- }
- for(unit=0; unit<NHP; unit++)
- if(as & (1<<unit))
- hpustart(unit);
- hpstart();
- }
-
- hpread(dev)
- {
-
- physio(hpstrategy, &rhpbuf, dev, B_READ);
- }
-
- hpwrite(dev)
- {
-
- physio(hpstrategy, &rhpbuf, dev, B_WRITE);
- }
-