-/* hp.c 3.8 %G% */
+/* hp.c 3.9 %G% */
/*
* RP06/RM03 disk driver
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/dk.h"
-#include "../h/dk.h"
#include "../h/buf.h"
#include "../h/conf.h"
#include "../h/dir.h"
#include "../h/user.h"
#include "../h/map.h"
+#include "../h/pte.h"
#include "../h/mba.h"
#include "../h/mtpr.h"
-#include "../h/pte.h"
+#include "../h/vm.h"
#define DK_N 0
#define DK_NMAX 1
int hpec2; /* Burst error bit pattern */
};
-#define HPADDR ((struct device *)(MBA0 + MBA_ERB))
+#define HPMBA MBA0
+#define HPMBANUM 0
+
#define NHP 2
#define RP 022
#define RM 024
long sz, bn;
struct size *sizes;
+ if ((mbaact&(1<<HPMBANUM)) == 0)
+ mbainit(HPMBANUM);
xunit = minor(bp->b_dev) & 077;
sz = bp->b_bcount;
sz = (sz+511) >> 9;
struct device *hpaddr;
/* determine device type */
- hpaddr = (struct device *)((int*)HPADDR + 32*unit);
+ hpaddr = mbadev(HPMBA, unit);
hp_type[unit] = hpaddr->hpdt;
}
if (hp_type[unit] == RM) {
int sn, cn, csn;
((struct mba_regs *)MBA0)->mba_cr |= MBAIE;
- HPADDR->hpas = 1<<unit;
+ hpaddr = mbadev(HPMBA, 0);
+ hpaddr->hpas = 1<<unit;
if(unit >= NHP)
return;
dp = &hputab[unit];
if((bp=dp->b_actf) == NULL)
return;
- hpaddr = (struct device *)((int *)HPADDR + 32*unit);
+ hpaddr = mbadev(HPMBA, unit);
if((hpaddr->hpds & VV) == 0) {
hpaddr->hpcs1 = PRESET|GO;
hpaddr->hpof = FMT22;
tn = sn/ns;
sn = sn%ns;
- hpaddr = (struct device *)((int *)HPADDR + 32*dn);
+ hpaddr = mbadev(HPMBA, dn);
if ((hpaddr->hpds & (DPR|MOL)) != (DPR|MOL)) {
hptab.b_active = 0;
hptab.b_errcnt = 0;
}
if(hptab.b_errcnt >= 16) {
hpaddr->hpof = hp_offset[hptab.b_errcnt & 017] | FMT22;
- ((struct mba_regs *)MBA0)->mba_cr &= ~MBAIE;
+ HPMBA->mba_cr &= ~MBAIE;
hpaddr->hpcs1 = OFFSET|GO;
while(hpaddr->hpds & PIP)
;
- ((struct mba_regs *)MBA0)->mba_cr |= MBAIE;
+ HPMBA->mba_cr |= MBAIE;
}
hpaddr->hpdc = cn;
hpaddr->hpda = (tn << 8) + sn;
dk_busy &= ~(1<<(DK_N+NHP));
else if (DK_N+unit <= DK_NMAX)
dk_busy &= ~(1<<(DK_N+unit));
- hpaddr = (struct device *)((int *)HPADDR + 32*unit);
- if (hpaddr->hpds & ERR || mbastat & MBAEBITS) { /* error bit */
+ hpaddr = mbadev(HPMBA, unit);
+ if (hpaddr->hpds & ERR || mbastat & MBAEBITS) {
while((hpaddr->hpds & DRY) == 0)
;
if(++hptab.b_errcnt > 28 || hpaddr->hper1&WLE)
- bp->b_flags |= B_ERROR; else
+ bp->b_flags |= B_ERROR;
+ else
hptab.b_active = 0;
if(hptab.b_errcnt > 27)
deverror(bp, mbastat, hpaddr->hper1);
}
hpaddr->hpcs1 = DCLR|GO;
if((hptab.b_errcnt&07) == 4) {
- ((struct mba_regs *)MBA0)->mba_cr &= ~MBAIE;
+ HPMBA->mba_cr &= ~MBAIE;
hpaddr->hpcs1 = RECAL|GO;
while(hpaddr->hpds & PIP)
;
- ((struct mba_regs *)MBA0)->mba_cr |= MBAIE;
+ HPMBA->mba_cr |= MBAIE;
}
}
if(hptab.b_active) {
if(hptab.b_errcnt) {
- ((struct mba_regs *)MBA0)->mba_cr &= ~MBAIE;
+ HPMBA->mba_cr &= ~MBAIE;
hpaddr->hpcs1 = RTC|GO;
while(hpaddr->hpds & PIP)
;
- ((struct mba_regs *)MBA0)->mba_cr |= MBAIE;
+ HPMBA->mba_cr |= MBAIE;
}
hptab.b_active = 0;
hptab.b_errcnt = 0;
dp->b_active = 0;
dp->b_errcnt = 0;
dp->b_actf = bp->av_forw;
- bp->b_resid = -(((struct mba_regs *)MBA0)->mba_bcr) & 0xffff;
+ bp->b_resid = -HPMBA->mba_bcr & 0xffff;
iodone(bp);
if(dp->b_actf)
hpustart(unit);
as &= ~(1<<unit);
} else {
if(as == 0)
- ((struct mba_regs *)MBA0)->mba_cr |= MBAIE;
+ HPMBA->mba_cr |= MBAIE;
}
for(unit=0; unit<NHP; unit++)
if(as & (1<<unit))
register struct device *rp;
register struct buf *bp;
{
- register i;
- register b, n, map, mix;
- register char *cp;
- register mask;
- short piget();
+ struct mba_regs *mbp = HPMBA;
+ register int i;
+ caddr_t addr;
+ int reg, bit, byte, npf, mask, o;
+ int dn, bn, cn, tn, sn, ns, nt;
extern char buffers[NBUF][BSIZE];
-
- b = (((((struct mba_regs *)MBA0)->mba_bcr&0xffff) +
- (bp->b_bcount) - 1)>>9)&0177;
- printf("%D ", bp->b_blkno+b);
+ struct pte mpte;
+
+ /*
+ * Npf is the number of sectors transferred before the sector
+ * containing the ECC error, and reg is the MBA register
+ * mapping (the first part of)the transfer.
+ * O is offset within a memory page of the first byte transferred.
+ */
+ npf = btop((mbp->mba_bcr&0xffff) + bp->b_bcount) - 1;
+ if (bp->b_flags&B_PHYS)
+ reg = 128 + npf;
+ else
+ reg = btop(bp->b_un.b_addr - buffers[0]) + npf;
+ o = (int)bp->b_un.b_addr & PGOFSET;
+ printf("%D ", bp->b_blkno + npf);
prdev("ECC", bp->b_dev);
mask = rp->hpec2&0xffff;
if (mask == 0) {
rp->hpof = FMT22;
- return(0);
+ return (0);
}
- i = (rp->hpec1&0xffff) - 1;
- n = i&017;
- i = (i&~017)>>3;
- if (bp->b_flags&B_PHYS)
- map = 128 + b;
- else
- map = ((bp->b_un.b_addr - (char *)buffers)>>9) + b;
- mix = i + ((int)bp->b_un.b_addr&0x1ff);
- i += b<<9;
- if ( i < bp->b_bcount) {
- cp = (char *)((((int *)MBA0_MAP)[map+(mix>>9)]&0x1fffff)<<9)+(mix&0x1ff);
- piput((int)cp,piget((int)cp)^(mask<<n));
+
+ /*
+ * Compute the byte and bit position of the error.
+ * The variable i is the byte offset in the transfer,
+ * the variable byte is the offset from a page boundary
+ * in main memory.
+ */
+ i = (rp->hpec1&0xffff) - 1; /* -1 makes 0 origin */
+ bit = i&017;
+ i = (i&~07)>>3;
+ byte = i + o;
+ /*
+ * Correct while possible bits remain of mask. Since mask
+ * contains 11 bits, we continue while the bit offset is > -11.
+ * Also watch out for end of this block and the end of the whole
+ * transfer.
+ */
+ while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) {
+ mpte = mbp->mba_map[reg+btop(byte)];
+ addr = ptob(mpte.pg_pfnum) + (byte & PGOFSET);
+ putmemc(addr, getmemc(addr)^(mask<<bit));
+ byte++;
+ i++;
+ bit -= 8;
}
- mix += 2;
- i += 2;
- if (i < bp->b_bcount) {
- cp = (char *)((((int *)MBA0_MAP)[map+(mix>>9)]&0x1fffff)<<9)+(mix&0x1ff);
- piput((int)cp,piget((int)cp)^(mask>>(16-n)));
+ hptab.b_active++; /* Either complete or continuing */
+ if (mbp->mba_bcr == 0)
+ return (0);
+ /*
+ * Have to continue the transfer... clear the drive,
+ * and compute the position where the transfer is to continue.
+ * We have completed npf+1 sectores of the transfer already;
+ * restart at offset o of next sector (i.e. in MBA register reg+1).
+ */
+ rp->hpcs1 = DCLR|GO;
+ dn = dkunit(bp);
+ bn = dkblock(bp);
+ if (hp_type[dn] == RM) {
+ ns = NRMSECT;
+ nt = NRMTRAC;
+ } else {
+ ns = NSECT;
+ nt = NTRAC;
}
- hptab.b_active++;
- if (((struct mba_regs *)MBA0)->mba_bcr) {
- i = bp->b_blkno%(NSECT*NTRAC);
- i = ((i/NSECT)<<8)+(i%NSECT);
- i = NSECT*(i>>8) + (i&0377) + b + 1;
- if (i >= NSECT*NTRAC) {
- i -= NSECT*NTRAC;
- rp->hpdc = bp->b_cylin + 1;
- } else
- rp->hpdc = bp->b_cylin;
- rp->hpda = ((i/NSECT)<<8) + (i%NSECT);
- rp->hpcs1 = DCLR|GO;
- ((struct mba_regs *)MBA0)->mba_sr = -1;
- ((struct mba_regs *)MBA0)->mba_var =
- ((map+1)<<9)|((int)bp->b_un.b_addr&0x1ff);
- rp->hpcs1 = RCOM|GO;
- return(1);
- } else
- return(0);
-}
-
-short
-piget(pad)
-{
- register b, savemap;
- register short s;
-
- savemap = (int)mmap;
- b = (pad>>9)&0x7fffff;
- *(int *)mmap = b|(PG_V|PG_KR);
- mtpr(TBIS, vmmap);
- s = *(short *)&vmmap[pad&0x1ff];
- *(int *)mmap = savemap;
- mtpr(TBIS, vmmap);
- return(s);
-}
-
-piput(pad, val)
-{
- register b, savemap;
- register short *p;
-
- savemap = (int)mmap;
- b = (pad>>9)&0x7fffff;
- *(int *)mmap = b|(PG_V|PG_KW);
- mtpr(TBIS, vmmap);
- p = (short *)&vmmap[pad&0x1ff];
- *p = val;
- *(int *)mmap = savemap;
- mtpr(TBIS, vmmap);
+ cn = bp->b_cylin;
+ sn = bn%(ns*nt) + npf + 1;
+ tn = sn/ns;
+ sn %= ns;
+ cn += tn/nt;
+ tn %= nt;
+ rp->hpdc = cn;
+ rp->hpda = (tn<<8) + sn;
+ mbp->mba_sr = -1;
+ mbp->mba_var = (int)ptob(reg+1) + o;
+ rp->hpcs1 = RCOM|GO;
+ return (1);
}
-/* ht.c 3.4 %G% */
+/* ht.c 3.5 %G% */
/*
* TJU16 tape driver
#include "../h/file.h"
#include "../h/user.h"
#include "../h/map.h"
+#include "../h/pte.h"
#include "../h/mba.h"
struct device
char h_flags[NUNIT];
daddr_t h_nxrec[NUNIT];
-#define HTADDR ((struct device *)(MBA1 + MBA_ERB))
+#define HTMBA MBA1
+#define HTMBANUM 1
#define GO 01
#define WCOM 060
{
register unit, ds;
+ if ((mbaact&(1<<HTMBANUM)) == 0)
+ mbainit(HTMBANUM);
httab.b_flags |= B_TAPE;
unit = minor(dev) & 03;
if (unit >= NUNIT || h_openf[unit]) {
register struct buf *bp;
register unit, den;
daddr_t blkno;
+ register struct device *htp = mbadev(HTMBA,0);
loop:
if ((bp = httab.b_actf) == NULL)
den = P800 | (unit&03);
if(unit >= 8)
den = P1600 | (unit&03);
- if((HTADDR->httc&03777) != den)
- HTADDR->httc = den;
+ if((htp->httc&03777) != den)
+ htp->httc = den;
unit &= 03;
blkno = h_blkno[unit];
if (bp == &chtbuf) {
if (bp->b_resid==NOP) {
- bp->b_resid = HTADDR->htds & 0xffff;
+ bp->b_resid = htp->htds & 0xffff;
goto next;
}
httab.b_active = SCOM;
- HTADDR->htfc = 0;
- HTADDR->htcs1 = bp->b_resid|GO;
+ htp->htfc = 0;
+ htp->htcs1 = bp->b_resid|GO;
return;
}
if (h_openf[unit] < 0 || dbtofsb(bp->b_blkno) > h_nxrec[unit])
goto abort;
if (blkno == dbtofsb(bp->b_blkno)) {
httab.b_active = SIO;
- HTADDR->htfc = -bp->b_bcount;
- mbastart(bp, (int *)HTADDR);
+ htp->htfc = -bp->b_bcount;
+ mbastart(bp, (int *)htp);
} else {
if (blkno < dbtofsb(bp->b_blkno)) {
httab.b_active = SSFOR;
- HTADDR->htfc = blkno - dbtofsb(bp->b_blkno);
- HTADDR->htcs1 = SFORW|GO;
+ htp->htfc = blkno - dbtofsb(bp->b_blkno);
+ htp->htcs1 = SFORW|GO;
} else {
httab.b_active = SSREV;
- HTADDR->htfc = dbtofsb(bp->b_blkno) - blkno;
- HTADDR->htcs1 = SREV|GO;
+ htp->htfc = dbtofsb(bp->b_blkno) - blkno;
+ htp->htcs1 = SREV|GO;
}
}
return;
register struct buf *bp;
register int unit, state;
int err;
+ register struct device *htp = mbadev(HTMBA,0);
if ((bp = httab.b_actf)==NULL)
return;
unit = minor(bp->b_dev) & 03;
state = httab.b_active;
httab.b_active = 0;
- if (HTADDR->htds&(ERR|EOT|TM) || mbastat & MBAEBITS) {
- err = HTADDR->hter & 0xffff;
+ if (htp->htds&(ERR|EOT|TM) || mbastat & MBAEBITS) {
+ err = htp->hter & 0xffff;
if ((mbastat & MBAEBITS) || (err&HARD))
state = 0;
if (bp == &rhtbuf)
err &= ~FCE;
- if ((bp->b_flags&B_READ) && (HTADDR->htds&PES))
+ if ((bp->b_flags&B_READ) && (htp->htds&PES))
err &= ~(CS|COR);
- if(HTADDR->htds&EOT || (HTADDR->htds&MOL)==0) {
+ if(htp->htds&EOT || (htp->htds&MOL)==0) {
if(h_openf[unit])
h_openf[unit] = -1;
}
- else if(HTADDR->htds&TM) {
- HTADDR->htfc = 0;
+ else if(htp->htds&TM) {
+ htp->htfc = 0;
h_nxrec[unit] = dbtofsb(bp->b_blkno);
state = SOK;
}
else if(state && err == 0)
state = SOK;
if(httab.b_errcnt > 4)
- deverror(bp, HTADDR->hter, mbastat);
- ((struct mba_regs *)MBA1)->mba_cr &= ~MBAIE;
- HTADDR->htcs1 = DCLR|GO;
- ((struct mba_regs *)MBA1)->mba_cr |= MBAIE;
+ deverror(bp, htp->hter, mbastat);
+ HTMBA->mba_cr &= ~MBAIE;
+ htp->htcs1 = DCLR|GO;
+ HTMBA->mba_cr |= MBAIE;
if (state==SIO && ++httab.b_errcnt < 10) {
httab.b_active = SRETRY;
h_blkno[unit]++;
- HTADDR->htfc = -1;
- HTADDR->htcs1 = SREV|GO;
+ htp->htfc = -1;
+ htp->htcs1 = SREV|GO;
return;
}
if (state!=SOK) {
bp->b_flags |= B_ERROR;
state = SIO;
}
- } else if (HTADDR->htcs1 < 0) { /* SC */
- if(HTADDR->htds & ERR) {
- ((struct mba_regs *)MBA1)->mba_cr &= ~MBAIE;
- HTADDR->htcs1 = DCLR|GO;
- ((struct mba_regs *)MBA1)->mba_cr |= MBAIE;
+ } else if (htp->htcs1 < 0) { /* SC */
+ if(htp->htds & ERR) {
+ HTMBA->mba_cr &= ~MBAIE;
+ htp->htcs1 = DCLR|GO;
+ HTMBA->mba_cr |= MBAIE;
}
}
switch(state) {
case SCOM:
httab.b_errcnt = 0;
httab.b_actf = bp->av_forw;
- bp->b_resid = - (HTADDR->htfc & 0xffff);
+ bp->b_resid = - (htp->htfc & 0xffff);
if (bp->b_flags & B_READ)
bp->b_resid += bp->b_bcount;
iodone(bp);
case SRETRY:
if((bp->b_flags&B_READ)==0) {
httab.b_active = SSFOR;
- HTADDR->htcs1 = ERASE|GO;
+ htp->htcs1 = ERASE|GO;
return;
}
case SSFOR:
case SSREV:
#define blk dbtofsb(bp->b_blkno)
- if(HTADDR->htds & TM) {
+ if(htp->htds & TM) {
if(state == SSREV) {
- h_nxrec[unit] = blk - (HTADDR->htfc&0xffff);
+ h_nxrec[unit] = blk - (htp->htfc&0xffff);
h_blkno[unit] = h_nxrec[unit];
} else {
- h_nxrec[unit] = blk + (HTADDR->htfc&0xffff) - 1;
- h_blkno[unit] = blk + (HTADDR->htfc & 0xffff);
+ h_nxrec[unit] = blk + (htp->htfc&0xffff) - 1;
+ h_blkno[unit] = blk + (htp->htfc & 0xffff);
}
} else
h_blkno[unit] = blk;
-/* mba.c 3.3 %G% */
+/* mba.c 3.4 %G% */
#include "../h/param.h"
#include "../h/buf.h"
#define MBARCOM 0x38
#define GO 01
-int mbaboff;
+extern char buffers[NBUF][BSIZE];
mbastart(bp, adcr)
-register struct buf *bp;
-int *adcr;
+ register struct buf *bp;
+ int *adcr;
{
register int i;
int npf;
int vaddr;
register struct mba_regs *mbap;
struct proc *rp;
- extern int mbanum[], *mbaloc[];
- extern char buffers[NBUF][BSIZE];
- mbap = (struct mba_regs *)mbaloc[mbanum[major(bp->b_dev)]];
+ mbap = mbainfo[mbanum[major(bp->b_dev)]].mi_loc;
if ((bp->b_flags & B_PHYS) == 0)
- vaddr = (bp->b_un.b_addr - (char *)buffers) + mbaboff;
+ vaddr = (bp->b_un.b_addr - buffers[0]);
else {
- io = (struct pte *)mbap;
- io += (MBA_MAP + 128*4)/4;
+ io = &mbap->mba_map[128];
v = btop(bp->b_un.b_addr);
o = (int)bp->b_un.b_addr & PGOFSET;
npf = btoc(bp->b_bcount + o);
*adcr = MBAWCOM | GO;
}
-mbainit()
+mbainit(mbanum)
+ int mbanum;
{
- register int *io0, *io1, *b, t, j;
- extern int *mbaloc[];
- extern char buffers[NBUF][BSIZE];
+ register struct pte *io, *b;
+ register int i;
+ register struct mba_info *mi;
+ register struct mba_regs *mbap;
+ unsigned v;
- io0 = mbaloc[0] + (MBA_MAP/4);
- io1 = mbaloc[1] + (MBA_MAP/4);
- b = (int *)Sysmap + ((((int) buffers)>>9)&PG_PFNUM);
- j = NBUF * CLSIZE + ((int)buffers & 0x1ff ? 1 : 0);
- do {
- t = PG_V | (*b++ & PG_PFNUM);
- *io0++ = t;
- *io1++ = t;
- } while (--j>0);
- *io0 = 0; /* invalidate next entry */
- *io1 = 0;
- mbaboff = (int)buffers & 0x1ff;
+ mi = &mbainfo[mbanum];
+ v = btop((int)mi->mi_phys);
+ b = mi->mi_map;
+ for (i = 0; i < 8192; i += NBPG) {
+ *(int *)b++ = PG_V | PG_KW | v;
+ mtpr(TBIS, ptob(v));
+ v++;
+ }
+ mbap = mi->mi_loc;
+ mbap->mba_cr = MBAINIT;
+ mbap->mba_cr = MBAIE;
+ io = mbap->mba_map;
+ b = &Sysmap[btop(((int)buffers[0])&0x7fffffff)];
+ for (i = NBUF * CLSIZE; i > 0; i--) {
+ *(int *)io++ = PG_V | b->pg_pfnum;
+ b++;
+ }
+ *(int *)io = 0;
+ mbaact |= (1<<mbanum);
}