1*1563Sbill /* ht.c 3.6 10/19/80 */ 222Sbill 3*1563Sbill #include "../conf/ht.h" 4*1563Sbill #if NHT > 0 522Sbill /* 622Sbill * TJU16 tape driver 722Sbill */ 822Sbill 922Sbill #include "../h/param.h" 1022Sbill #include "../h/systm.h" 1122Sbill #include "../h/buf.h" 1222Sbill #include "../h/conf.h" 1322Sbill #include "../h/dir.h" 1422Sbill #include "../h/file.h" 1522Sbill #include "../h/user.h" 1622Sbill #include "../h/map.h" 17420Sbill #include "../h/pte.h" 1822Sbill #include "../h/mba.h" 1922Sbill 2022Sbill struct device 2122Sbill { 2222Sbill int htcs1; 2322Sbill int htds; 2422Sbill int hter; 2522Sbill int htmr; 2622Sbill int htas; 2722Sbill int htfc; 2822Sbill int htdt; 2922Sbill int htck; 3022Sbill int htsn; 3122Sbill int httc; 3222Sbill }; 3322Sbill 3422Sbill struct buf httab; 3522Sbill struct buf rhtbuf; 3622Sbill struct buf chtbuf; 3722Sbill 38*1563Sbill #define NHT 1 3922Sbill #define INF 1000000 4022Sbill 41*1563Sbill char h_openf[NHT]; 42*1563Sbill daddr_t h_blkno[NHT]; 43*1563Sbill char h_flags[NHT]; 44*1563Sbill daddr_t h_nxrec[NHT]; 4522Sbill 4622Sbill #define GO 01 4722Sbill #define WCOM 060 4822Sbill #define RCOM 070 4922Sbill #define NOP 0 5022Sbill #define WEOF 026 5122Sbill #define SFORW 030 5222Sbill #define SREV 032 5322Sbill #define ERASE 024 5422Sbill #define REW 06 5522Sbill #define DCLR 010 5622Sbill #define P800 01700 /* 800 + pdp11 mode */ 5722Sbill #define P1600 02300 /* 1600 + pdp11 mode */ 5822Sbill #define IENABLE 0100 5922Sbill #define RDY 0200 6022Sbill #define TM 04 6122Sbill #define DRY 0200 6222Sbill #define EOT 02000 6322Sbill #define CS 02000 6422Sbill #define COR 0100000 6522Sbill #define PES 040 6622Sbill #define WRL 04000 6722Sbill #define MOL 010000 6822Sbill #define ERR 040000 6922Sbill #define FCE 01000 7022Sbill #define TRE 040000 7122Sbill #define HARD 064023 /* UNS|OPI|NEF|FMT|RMR|ILR|ILF */ 7222Sbill 7322Sbill #define SIO 1 7422Sbill #define SSFOR 2 7522Sbill #define SSREV 3 7622Sbill #define SRETRY 4 7722Sbill #define SCOM 5 7822Sbill #define SOK 6 7922Sbill 8022Sbill #define H_WRITTEN 1 8122Sbill 8222Sbill htopen(dev, flag) 8322Sbill { 8422Sbill register unit, ds; 8522Sbill 86420Sbill if ((mbaact&(1<<HTMBANUM)) == 0) 87420Sbill mbainit(HTMBANUM); 8822Sbill httab.b_flags |= B_TAPE; 8922Sbill unit = minor(dev) & 03; 90*1563Sbill if (unit >= NHT || h_openf[unit]) { 9122Sbill u.u_error = ENXIO; 9222Sbill return; 9322Sbill } 9422Sbill h_blkno[unit] = 0; 9522Sbill h_nxrec[unit] = INF; 9622Sbill h_flags[unit] = 0; 9722Sbill ds = hcommand(dev, NOP); 9822Sbill if ((ds&MOL)==0 || (flag && (ds&WRL))) 9922Sbill u.u_error = ENXIO; 10022Sbill if (u.u_error==0) 10122Sbill h_openf[unit]++; 10222Sbill } 10322Sbill 10422Sbill htclose(dev, flag) 10522Sbill { 10622Sbill register int unit; 10722Sbill 10822Sbill unit = minor(dev) & 03; 10922Sbill if (flag == FWRITE || ((flag&FWRITE) && (h_flags[unit]&H_WRITTEN))) { 110128Sbill (void) hcommand(dev, WEOF); 111128Sbill (void) hcommand(dev, WEOF); 112128Sbill (void) hcommand(dev, SREV); 11322Sbill } 11422Sbill if((minor(dev)&4) == 0) /* no 4 -> rewind */ 115128Sbill (void) hcommand(dev, REW); 11622Sbill h_openf[unit] = 0; 11722Sbill } 11822Sbill 11922Sbill hcommand(dev, com) 12022Sbill { 12122Sbill register struct buf *bp; 12222Sbill 12322Sbill bp = &chtbuf; 124128Sbill (void) spl5(); 12522Sbill while(bp->b_flags&B_BUSY) { 12622Sbill bp->b_flags |= B_WANTED; 12722Sbill sleep((caddr_t)bp, PRIBIO); 12822Sbill } 129128Sbill (void) spl0(); 13022Sbill bp->b_dev = dev; 13122Sbill bp->b_resid = com; 13222Sbill bp->b_blkno = 0; 13322Sbill bp->b_flags = B_BUSY|B_READ; 13422Sbill htstrategy(bp); 13522Sbill iowait(bp); 13622Sbill if(bp->b_flags&B_WANTED) 13722Sbill wakeup((caddr_t)bp); 13822Sbill bp->b_flags = 0; 13922Sbill return(bp->b_resid); 14022Sbill } 14122Sbill 14222Sbill htstrategy(bp) 14322Sbill register struct buf *bp; 14422Sbill { 14522Sbill register daddr_t *p; 14622Sbill 14722Sbill if(bp != &chtbuf) { 14822Sbill p = &h_nxrec[minor(bp->b_dev)&03]; 14922Sbill if(dbtofsb(bp->b_blkno) > *p) { 15022Sbill bp->b_flags |= B_ERROR; 15122Sbill bp->b_error = ENXIO; 15222Sbill iodone(bp); 15322Sbill return; 15422Sbill } 15522Sbill if(dbtofsb(bp->b_blkno) == *p && bp->b_flags&B_READ) { 15622Sbill bp->b_resid = bp->b_bcount; 15722Sbill clrbuf(bp); 15822Sbill iodone(bp); 15922Sbill return; 16022Sbill } 16122Sbill if ((bp->b_flags&B_READ)==0) { 16222Sbill *p = dbtofsb(bp->b_blkno) + 1; 16322Sbill h_flags[minor(bp->b_dev)&03] |= H_WRITTEN; 16422Sbill } 16522Sbill } 16622Sbill bp->av_forw = NULL; 167128Sbill (void) spl5(); 16822Sbill if (httab.b_actf == NULL) 16922Sbill httab.b_actf = bp; 17022Sbill else 17122Sbill httab.b_actl->av_forw = bp; 17222Sbill httab.b_actl = bp; 17322Sbill if (httab.b_active==0) 17422Sbill htstart(); 175128Sbill (void) spl0(); 17622Sbill } 17722Sbill 17822Sbill htstart() 17922Sbill { 18022Sbill register struct buf *bp; 18122Sbill register unit, den; 18222Sbill daddr_t blkno; 183420Sbill register struct device *htp = mbadev(HTMBA,0); 18422Sbill 18522Sbill loop: 18622Sbill if ((bp = httab.b_actf) == NULL) 18722Sbill return; 18822Sbill unit = minor(bp->b_dev); 18922Sbill den = P800 | (unit&03); 19022Sbill if(unit >= 8) 19122Sbill den = P1600 | (unit&03); 192420Sbill if((htp->httc&03777) != den) 193420Sbill htp->httc = den; 19422Sbill unit &= 03; 19522Sbill blkno = h_blkno[unit]; 19622Sbill if (bp == &chtbuf) { 19722Sbill if (bp->b_resid==NOP) { 198420Sbill bp->b_resid = htp->htds & 0xffff; 19922Sbill goto next; 20022Sbill } 20122Sbill httab.b_active = SCOM; 202420Sbill htp->htfc = 0; 203420Sbill htp->htcs1 = bp->b_resid|GO; 20422Sbill return; 20522Sbill } 20622Sbill if (h_openf[unit] < 0 || dbtofsb(bp->b_blkno) > h_nxrec[unit]) 20722Sbill goto abort; 20822Sbill if (blkno == dbtofsb(bp->b_blkno)) { 20922Sbill httab.b_active = SIO; 210420Sbill htp->htfc = -bp->b_bcount; 211420Sbill mbastart(bp, (int *)htp); 21222Sbill } else { 21322Sbill if (blkno < dbtofsb(bp->b_blkno)) { 21422Sbill httab.b_active = SSFOR; 215420Sbill htp->htfc = blkno - dbtofsb(bp->b_blkno); 216420Sbill htp->htcs1 = SFORW|GO; 21722Sbill } else { 21822Sbill httab.b_active = SSREV; 219420Sbill htp->htfc = dbtofsb(bp->b_blkno) - blkno; 220420Sbill htp->htcs1 = SREV|GO; 22122Sbill } 22222Sbill } 22322Sbill return; 22422Sbill 22522Sbill abort: 22622Sbill bp->b_flags |= B_ERROR; 22722Sbill 22822Sbill next: 22922Sbill httab.b_actf = bp->av_forw; 23022Sbill iodone(bp); 23122Sbill goto loop; 23222Sbill } 23322Sbill 23422Sbill /*ARGSUSED*/ 23522Sbill htintr(mbastat, as) 23622Sbill { 23722Sbill register struct buf *bp; 23822Sbill register int unit, state; 23922Sbill int err; 240420Sbill register struct device *htp = mbadev(HTMBA,0); 24122Sbill 24222Sbill if ((bp = httab.b_actf)==NULL) 24322Sbill return; 24422Sbill unit = minor(bp->b_dev) & 03; 24522Sbill state = httab.b_active; 24622Sbill httab.b_active = 0; 247420Sbill if (htp->htds&(ERR|EOT|TM) || mbastat & MBAEBITS) { 248420Sbill err = htp->hter & 0xffff; 24922Sbill if ((mbastat & MBAEBITS) || (err&HARD)) 25022Sbill state = 0; 25122Sbill if (bp == &rhtbuf) 25222Sbill err &= ~FCE; 253420Sbill if ((bp->b_flags&B_READ) && (htp->htds&PES)) 25422Sbill err &= ~(CS|COR); 255420Sbill if(htp->htds&EOT || (htp->htds&MOL)==0) { 25622Sbill if(h_openf[unit]) 25722Sbill h_openf[unit] = -1; 25822Sbill } 259420Sbill else if(htp->htds&TM) { 260420Sbill htp->htfc = 0; 26122Sbill h_nxrec[unit] = dbtofsb(bp->b_blkno); 26222Sbill state = SOK; 26322Sbill } 26422Sbill else if(state && err == 0) 26522Sbill state = SOK; 26622Sbill if(httab.b_errcnt > 4) 267420Sbill deverror(bp, htp->hter, mbastat); 268420Sbill HTMBA->mba_cr &= ~MBAIE; 269420Sbill htp->htcs1 = DCLR|GO; 270420Sbill HTMBA->mba_cr |= MBAIE; 27122Sbill if (state==SIO && ++httab.b_errcnt < 10) { 27222Sbill httab.b_active = SRETRY; 27322Sbill h_blkno[unit]++; 274420Sbill htp->htfc = -1; 275420Sbill htp->htcs1 = SREV|GO; 27622Sbill return; 27722Sbill } 27822Sbill if (state!=SOK) { 27922Sbill bp->b_flags |= B_ERROR; 28022Sbill state = SIO; 28122Sbill } 282420Sbill } else if (htp->htcs1 < 0) { /* SC */ 283420Sbill if(htp->htds & ERR) { 284420Sbill HTMBA->mba_cr &= ~MBAIE; 285420Sbill htp->htcs1 = DCLR|GO; 286420Sbill HTMBA->mba_cr |= MBAIE; 28722Sbill } 28822Sbill } 28922Sbill switch(state) { 29022Sbill case SIO: 29122Sbill case SOK: 29222Sbill h_blkno[unit]++; 29322Sbill 29422Sbill case SCOM: 29522Sbill httab.b_errcnt = 0; 29622Sbill httab.b_actf = bp->av_forw; 297420Sbill bp->b_resid = - (htp->htfc & 0xffff); 29822Sbill if (bp->b_flags & B_READ) 29922Sbill bp->b_resid += bp->b_bcount; 30022Sbill iodone(bp); 30122Sbill break; 30222Sbill 30322Sbill case SRETRY: 30422Sbill if((bp->b_flags&B_READ)==0) { 30522Sbill httab.b_active = SSFOR; 306420Sbill htp->htcs1 = ERASE|GO; 30722Sbill return; 30822Sbill } 30922Sbill 31022Sbill case SSFOR: 31122Sbill case SSREV: 312220Sbill #define blk dbtofsb(bp->b_blkno) 313420Sbill if(htp->htds & TM) { 31422Sbill if(state == SSREV) { 315420Sbill h_nxrec[unit] = blk - (htp->htfc&0xffff); 31622Sbill h_blkno[unit] = h_nxrec[unit]; 31722Sbill } else { 318420Sbill h_nxrec[unit] = blk + (htp->htfc&0xffff) - 1; 319420Sbill h_blkno[unit] = blk + (htp->htfc & 0xffff); 32022Sbill } 32122Sbill } else 322220Sbill h_blkno[unit] = blk; 32322Sbill break; 32422Sbill 32522Sbill default: 32622Sbill return; 32722Sbill } 32822Sbill htstart(); 32922Sbill } 33022Sbill 33122Sbill htread(dev) 33222Sbill { 33322Sbill htphys(dev); 33422Sbill physio(htstrategy, &rhtbuf, dev, B_READ, minphys); 33522Sbill } 33622Sbill 33722Sbill htwrite(dev) 33822Sbill { 33922Sbill htphys(dev); 34022Sbill physio(htstrategy, &rhtbuf, dev, B_WRITE, minphys); 34122Sbill } 34222Sbill 34322Sbill htphys(dev) 34422Sbill { 34522Sbill register unit; 34622Sbill daddr_t a; 34722Sbill 34822Sbill unit = minor(dev) & 03; 349*1563Sbill if(unit < NHT) { 35022Sbill a = u.u_offset >> 9; 35122Sbill h_blkno[unit] = dbtofsb(a); 35222Sbill h_nxrec[unit] = dbtofsb(a)+1; 35322Sbill } 35422Sbill } 355*1563Sbill #endif 356