From: Bill Joy Date: Thu, 10 Apr 1980 07:03:18 +0000 (-0800) Subject: date and time created 80/04/09 16:03:18 by bill X-Git-Tag: BSD-4^3~1278 X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/commitdiff_plain/786dff003fc45a4b867d2f2d0ef327b716601106 date and time created 80/04/09 16:03:18 by bill SCCS-vsn: sys/vax/mba/ht.c 3.1 --- diff --git a/usr/src/sys/vax/mba/ht.c b/usr/src/sys/vax/mba/ht.c new file mode 100644 index 0000000000..b3b2386300 --- /dev/null +++ b/usr/src/sys/vax/mba/ht.c @@ -0,0 +1,351 @@ +/* ht.c 3.1 %H% */ + +/* + * TJU16 tape driver + */ + +#include "../h/param.h" +#include "../h/systm.h" +#include "../h/buf.h" +#include "../h/conf.h" +#include "../h/dir.h" +#include "../h/file.h" +#include "../h/user.h" +#include "../h/map.h" +#include "../h/mba.h" + +struct device +{ + int htcs1; + int htds; + int hter; + int htmr; + int htas; + int htfc; + int htdt; + int htck; + int htsn; + int httc; +}; + +struct buf httab; +struct buf rhtbuf; +struct buf chtbuf; + +#define NUNIT 1 +#define BUNIT 2 +#define INF 1000000 + +char h_openf[NUNIT]; +daddr_t h_blkno[NUNIT]; +char h_flags[NUNIT]; +daddr_t h_nxrec[NUNIT]; + +#define HTADDR ((struct device *)(MBA1 + MBA_ERB)) + +#define GO 01 +#define WCOM 060 +#define RCOM 070 +#define NOP 0 +#define WEOF 026 +#define SFORW 030 +#define SREV 032 +#define ERASE 024 +#define REW 06 +#define DCLR 010 +#define P800 01700 /* 800 + pdp11 mode */ +#define P1600 02300 /* 1600 + pdp11 mode */ +#define IENABLE 0100 +#define RDY 0200 +#define TM 04 +#define DRY 0200 +#define EOT 02000 +#define CS 02000 +#define COR 0100000 +#define PES 040 +#define WRL 04000 +#define MOL 010000 +#define ERR 040000 +#define FCE 01000 +#define TRE 040000 +#define HARD 064023 /* UNS|OPI|NEF|FMT|RMR|ILR|ILF */ + +#define SIO 1 +#define SSFOR 2 +#define SSREV 3 +#define SRETRY 4 +#define SCOM 5 +#define SOK 6 + +#define H_WRITTEN 1 + +htopen(dev, flag) +{ + register unit, ds; + + httab.b_flags |= B_TAPE; + unit = minor(dev) & 03; + if (unit >= NUNIT || h_openf[unit]) { + u.u_error = ENXIO; + return; + } + h_blkno[unit] = 0; + h_nxrec[unit] = INF; + h_flags[unit] = 0; + ds = hcommand(dev, NOP); + if ((ds&MOL)==0 || (flag && (ds&WRL))) + u.u_error = ENXIO; + if (u.u_error==0) + h_openf[unit]++; +} + +htclose(dev, flag) +{ + register int unit; + + unit = minor(dev) & 03; + if (flag == FWRITE || ((flag&FWRITE) && (h_flags[unit]&H_WRITTEN))) { + VOID hcommand(dev, WEOF); + VOID hcommand(dev, WEOF); + VOID hcommand(dev, SREV); + } +/* VOID hcommand(dev, REW); */ +/* for 'mtm' file positioning */ + if((minor(dev)&4) == 0) /* no 4 -> rewind */ + VOID hcommand(dev, REW); + h_openf[unit] = 0; +} + +hcommand(dev, com) +{ + register struct buf *bp; + + bp = &chtbuf; + VOID spl5(); + while(bp->b_flags&B_BUSY) { + bp->b_flags |= B_WANTED; + sleep((caddr_t)bp, PRIBIO); + } + VOID spl0(); + bp->b_dev = dev; + bp->b_resid = com; + bp->b_blkno = 0; + bp->b_flags = B_BUSY|B_READ; + htstrategy(bp); + iowait(bp); + if(bp->b_flags&B_WANTED) + wakeup((caddr_t)bp); + bp->b_flags = 0; + return(bp->b_resid); +} + +htstrategy(bp) +register struct buf *bp; +{ + register daddr_t *p; + + if(bp != &chtbuf) { + p = &h_nxrec[minor(bp->b_dev)&03]; + if(dbtofsb(bp->b_blkno) > *p) { + bp->b_flags |= B_ERROR; + bp->b_error = ENXIO; + iodone(bp); + return; + } + if(dbtofsb(bp->b_blkno) == *p && bp->b_flags&B_READ) { + bp->b_resid = bp->b_bcount; + clrbuf(bp); + iodone(bp); + return; + } + if ((bp->b_flags&B_READ)==0) { + *p = dbtofsb(bp->b_blkno) + 1; + h_flags[minor(bp->b_dev)&03] |= H_WRITTEN; + } + } + bp->av_forw = NULL; + VOID spl5(); + if (httab.b_actf == NULL) + httab.b_actf = bp; + else + httab.b_actl->av_forw = bp; + httab.b_actl = bp; + if (httab.b_active==0) + htstart(); + VOID spl0(); +} + +htstart() +{ + register struct buf *bp; + register unit, den; + daddr_t blkno; + + loop: + if ((bp = httab.b_actf) == NULL) + return; + unit = minor(bp->b_dev); + den = P800 | (unit&03); + if(unit >= 8) + den = P1600 | (unit&03); + if((HTADDR->httc&03777) != den) + HTADDR->httc = den; + unit &= 03; + blkno = h_blkno[unit]; + if (bp == &chtbuf) { + if (bp->b_resid==NOP) { + bp->b_resid = HTADDR->htds & 0xffff; + goto next; + } + httab.b_active = SCOM; + HTADDR->htfc = 0; + HTADDR->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); + } else { + if (blkno < dbtofsb(bp->b_blkno)) { + httab.b_active = SSFOR; + HTADDR->htfc = blkno - dbtofsb(bp->b_blkno); + HTADDR->htcs1 = SFORW|GO; + } else { + httab.b_active = SSREV; + HTADDR->htfc = dbtofsb(bp->b_blkno) - blkno; + HTADDR->htcs1 = SREV|GO; + } + } + return; + + abort: + bp->b_flags |= B_ERROR; + + next: + httab.b_actf = bp->av_forw; + iodone(bp); + goto loop; +} + +/*ARGSUSED*/ +htintr(mbastat, as) +{ + register struct buf *bp; + register int unit, state; + int err; + + 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 ((mbastat & MBAEBITS) || (err&HARD)) + state = 0; + if (bp == &rhtbuf) + err &= ~FCE; + if ((bp->b_flags&B_READ) && (HTADDR->htds&PES)) + err &= ~(CS|COR); + if(HTADDR->htds&EOT || (HTADDR->htds&MOL)==0) { + if(h_openf[unit]) + h_openf[unit] = -1; + } + else if(HTADDR->htds&TM) { + HTADDR->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; + if (state==SIO && ++httab.b_errcnt < 10) { + httab.b_active = SRETRY; + h_blkno[unit]++; + HTADDR->htfc = -1; + HTADDR->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; + } + } + switch(state) { + case SIO: + case SOK: + h_blkno[unit]++; + + case SCOM: + httab.b_errcnt = 0; + httab.b_actf = bp->av_forw; + bp->b_resid = - (HTADDR->htfc & 0xffff); + if (bp->b_flags & B_READ) + bp->b_resid += bp->b_bcount; + iodone(bp); + break; + + case SRETRY: + if((bp->b_flags&B_READ)==0) { + httab.b_active = SSFOR; + HTADDR->htcs1 = ERASE|GO; + return; + } + + case SSFOR: + case SSREV: + if(HTADDR->htds & TM) { + if(state == SSREV) { + h_nxrec[unit] = dbtofsb(bp->b_blkno) - (HTADDR->htfc&0xffff); + h_blkno[unit] = h_nxrec[unit]; + } else { + h_nxrec[unit] = dbtofsb(bp->b_blkno) + (HTADDR->htfc & 0xffff) - 1; + h_blkno[unit] = dbtofsb(bp->b_blkno) + (HTADDR->htfc & 0xffff); + } + } else + h_blkno[unit] = dbtofsb(bp->b_blkno); + break; + + default: + return; + } + htstart(); +} + +htread(dev) +{ + htphys(dev); + physio(htstrategy, &rhtbuf, dev, B_READ, minphys); +} + +htwrite(dev) +{ + htphys(dev); + physio(htstrategy, &rhtbuf, dev, B_WRITE, minphys); +} + +htphys(dev) +{ + register unit; + daddr_t a; + + unit = minor(dev) & 03; + if(unit < NUNIT) { + a = u.u_offset >> 9; + h_blkno[unit] = dbtofsb(a); + h_nxrec[unit] = dbtofsb(a)+1; + } +}