Annotation of 41BSD/sys/newsys/ht.c, revision 1.1.1.1

1.1       root        1: /*     ht.c    3.5     7/29/80 */
                      2: 
                      3: /*
                      4:  * TJU16 tape driver
                      5:  * IOCTRL calls added - Ken Birman
                      6:  */
                      7: 
                      8: #include "../ch/param.h"
                      9: #include "../ch/systm.h"
                     10: #include "../ch/buf.h"
                     11: #include "../ch/conf.h"
                     12: #include "../ch/dir.h"
                     13: #include "../ch/user.h"
                     14: #include "../ch/file.h"
                     15: #include "../ch/map.h"
                     16: #include "../ch/pte.h"
                     17: #include "../ch/mba.h"
                     18: 
                     19: struct device
                     20: {
                     21:        int     htcs1;
                     22:        int     htds;
                     23:        int     hter;
                     24:        int     htmr;
                     25:        int     htas;
                     26:        int     htfc;
                     27:        int     htdt;
                     28:        int     htck;
                     29:        int     htsn;
                     30:        int     httc;
                     31: };
                     32: 
                     33: struct buf     httab;
                     34: struct buf     rhtbuf;
                     35: struct buf     chtbuf;
                     36: 
                     37: #define        NUNIT   1
                     38: #define        BUNIT   2
                     39: #define        INF     1000000
                     40: 
                     41: char   h_openf[NUNIT];
                     42: daddr_t        h_blkno[NUNIT];
                     43: char   h_flags[NUNIT];
                     44: daddr_t        h_nxrec[NUNIT];
                     45: 
                     46: #define        HTMBA           MBA1
                     47: #define        HTMBANUM        1
                     48: 
                     49: #define        GO      01
                     50: #define        WCOM    060
                     51: #define        RCOM    070
                     52: #define        NOP     0
                     53: #define        WEOF    026
                     54: #define        SFORW   030
                     55: #define        SREV    032
                     56: #define        ERASE   024
                     57: #define        REW     06
                     58: #define        DCLR    010
                     59: #define        P800    01700           /* 800 + pdp11 mode */
                     60: #define        P1600   02300           /* 1600 + pdp11 mode */
                     61: #define        IENABLE 0100
                     62: #define        RDY     0200
                     63: #define        TM      04
                     64: #define        DRY     0200
                     65: #define        EOT     02000
                     66: #define        CS      02000
                     67: #define        COR     0100000
                     68: #define        PES     040
                     69: #define        WRL     04000
                     70: #define        MOL     010000
                     71: #define        ERR     040000
                     72: #define        FCE     01000
                     73: #define        TRE     040000
                     74: #define        HARD    064023  /* UNS|OPI|NEF|FMT|RMR|ILR|ILF */
                     75: 
                     76: #define        SIO     1
                     77: #define        SSFOR   2
                     78: #define        SSREV   3
                     79: #define        SRETRY  4
                     80: #define        SCOM    5
                     81: #define        SOK     6
                     82: 
                     83: #define        b_repcnt  b_bcount      /* Command repetition counter */
                     84: #define        b_command b_resid       /* Command to do */
                     85: #define        b_status  b_resid       /* Status after a tcommand */
                     86: 
                     87: 
                     88: #define        H_WRITTEN 1
                     89: 
                     90: htopen(dev, flag)
                     91: {
                     92:        register unit, ds;
                     93: 
                     94:        if ((mbaact&(1<<HTMBANUM)) == 0)
                     95:                mbainit(HTMBANUM);
                     96:        httab.b_flags |= B_TAPE;
                     97:        unit = minor(dev) & 03;
                     98:        if (unit >= NUNIT || h_openf[unit]) {
                     99:                u.u_error = ENXIO;
                    100:                return;
                    101:        }
                    102:        h_blkno[unit] = 0;
                    103:        h_nxrec[unit] = INF;
                    104:        h_flags[unit] = 0;
                    105:        ds = hcommand(dev, NOP, 1);
                    106:        if ((ds&MOL)==0 || (flag && (ds&WRL)))
                    107:                u.u_error = ENXIO;
                    108:        if (u.u_error==0)
                    109:                h_openf[unit]++;
                    110: }
                    111: 
                    112: htclose(dev, flag)
                    113: {
                    114:        register int unit;
                    115: 
                    116:        unit = minor(dev) & 03;
                    117:        if (flag == FWRITE || ((flag&FWRITE) && (h_flags[unit]&H_WRITTEN))) {
                    118:                (void) hcommand(dev, WEOF, 2);
                    119:                (void) hcommand(dev, SREV, 1);
                    120:        }
                    121:        if((minor(dev)&4) == 0) /* no 4 -> rewind */
                    122:                (void) hcommand(dev, REW, 1);
                    123:        h_openf[unit] = 0;
                    124: }
                    125: 
                    126: hcommand(dev, com, cnt)
                    127: {
                    128:        register struct buf *bp;
                    129: 
                    130:        bp = &chtbuf;
                    131:        (void) spl5();
                    132:        while(bp->b_flags&B_BUSY) {
                    133:                bp->b_flags |= B_WANTED;
                    134:                sleep((caddr_t)bp, PRIBIO);
                    135:        }
                    136:        (void) spl0();
                    137:        bp->b_dev = dev;
                    138:        bp->b_command = com;
                    139:        bp->b_repcnt = -cnt;
                    140:        bp->b_blkno = 0;
                    141:        bp->b_flags = B_BUSY|B_READ;
                    142:        htstrategy(bp);
                    143:        iowait(bp);
                    144:        if(bp->b_flags&B_WANTED)
                    145:                wakeup((caddr_t)bp);
                    146:        bp->b_flags = 0;
                    147:        return(bp->b_status);
                    148: }
                    149: 
                    150: htstrategy(bp)
                    151: register struct buf *bp;
                    152: {
                    153:        register daddr_t *p;
                    154: 
                    155:        if(bp != &chtbuf) {
                    156:                p = &h_nxrec[minor(bp->b_dev)&03];
                    157:                if(dbtofsb(bp->b_blkno) > *p) {
                    158:                        bp->b_flags |= B_ERROR;
                    159:                        bp->b_error = ENXIO;
                    160:                        iodone(bp);
                    161:                        return;
                    162:                }
                    163:                if(dbtofsb(bp->b_blkno) == *p && bp->b_flags&B_READ) {
                    164:                        bp->b_resid = bp->b_bcount;
                    165:                        clrbuf(bp);
                    166:                        iodone(bp);
                    167:                        return;
                    168:                }
                    169:                if ((bp->b_flags&B_READ)==0) {
                    170:                        *p = dbtofsb(bp->b_blkno) + 1;
                    171:                        h_flags[minor(bp->b_dev)&03] |=  H_WRITTEN;
                    172:                }
                    173:        }
                    174:        bp->av_forw = NULL;
                    175:        (void) spl5();
                    176:        if (httab.b_actf == NULL)
                    177:                httab.b_actf = bp;
                    178:        else
                    179:                httab.b_actl->av_forw = bp;
                    180:        httab.b_actl = bp;
                    181:        if (httab.b_active==0)
                    182:                htstart();
                    183:        (void) spl0();
                    184: }
                    185: 
                    186: htstart()
                    187: {
                    188:        register struct buf *bp;
                    189:        register unit, den;
                    190:        daddr_t blkno;
                    191:        register struct device *htp = mbadev(HTMBA,0);
                    192: 
                    193:     loop:
                    194:        if ((bp = httab.b_actf) == NULL)
                    195:                return;
                    196:        unit = minor(bp->b_dev);
                    197:        den = P800 | (unit&03);
                    198:        if(unit >= 8)
                    199:                den = P1600 | (unit&03);
                    200:        if((htp->httc&03777) != den)
                    201:                htp->httc = den;
                    202:        unit &= 03;
                    203:        blkno = h_blkno[unit];
                    204:        if (bp == &chtbuf) {
                    205:                if (bp->b_command==NOP) {
                    206:                        bp->b_status = htp->htds & 0xffff;
                    207:                        goto next;
                    208:                }
                    209:                httab.b_active = SCOM;
                    210:                if(bp->b_command == SREV || bp->b_command == SFORW)
                    211:                        htp->htfc = bp->b_repcnt;
                    212:                else
                    213:                        htp->htfc = 0;
                    214:                htp->htcs1 = bp->b_command|GO;
                    215:                return;
                    216:        }
                    217:        if (h_openf[unit] < 0 || dbtofsb(bp->b_blkno) > h_nxrec[unit])
                    218:                goto abort;
                    219:        if (blkno == dbtofsb(bp->b_blkno)) {
                    220:                httab.b_active = SIO;
                    221:                htp->htfc = -bp->b_bcount;
                    222:                mbastart(bp, (int *)htp);
                    223:        } else {
                    224:                if (blkno < dbtofsb(bp->b_blkno)) {
                    225:                        httab.b_active = SSFOR;
                    226:                        htp->htfc = blkno - dbtofsb(bp->b_blkno);
                    227:                        htp->htcs1 = SFORW|GO;
                    228:                } else {
                    229:                        httab.b_active = SSREV;
                    230:                        htp->htfc = dbtofsb(bp->b_blkno) - blkno;
                    231:                        htp->htcs1 = SREV|GO;
                    232:                }
                    233:        }
                    234:        return;
                    235: 
                    236:     abort:
                    237:        bp->b_flags |= B_ERROR;
                    238: 
                    239:     next:
                    240:        httab.b_actf = bp->av_forw;
                    241:        iodone(bp);
                    242:        goto loop;
                    243: }
                    244: 
                    245: /*ARGSUSED*/
                    246: htintr(mbastat, as)
                    247: {
                    248:        register struct buf *bp;
                    249:        register int unit, state;
                    250:        int err;
                    251:        register struct device *htp = mbadev(HTMBA,0);
                    252: 
                    253:        if ((bp = httab.b_actf)==NULL)
                    254:                return;
                    255:        unit = minor(bp->b_dev) & 03;
                    256:        state = httab.b_active;
                    257:        httab.b_active = 0;
                    258:        if (htp->htds&(ERR|EOT|TM) || mbastat & MBAEBITS) {
                    259:                err = htp->hter & 0xffff;
                    260:                if ((mbastat & MBAEBITS) || (err&HARD))
                    261:                        state = 0;
                    262:                if (bp == &rhtbuf)
                    263:                        err &= ~FCE;
                    264:                if ((bp->b_flags&B_READ) && (htp->htds&PES))
                    265:                        err &= ~(CS|COR);
                    266:                if(htp->htds&EOT || (htp->htds&MOL)==0) {
                    267:                        if(h_openf[unit])
                    268:                                h_openf[unit] = -1;
                    269:                }
                    270:                else if(htp->htds&TM) {
                    271:                        htp->htfc = 0;
                    272:                        h_nxrec[unit] = dbtofsb(bp->b_blkno);
                    273:                        state = SOK;
                    274:                }
                    275:                else if(state && err == 0)
                    276:                        state = SOK;
                    277:                if(httab.b_errcnt > 4)
                    278:                        deverror(bp, htp->hter, mbastat);
                    279:                HTMBA->mba_cr &= ~MBAIE;
                    280:                htp->htcs1 = DCLR|GO;
                    281:                HTMBA->mba_cr |= MBAIE;
                    282:                if (state==SIO && ++httab.b_errcnt < 10) {
                    283:                        httab.b_active = SRETRY;
                    284:                        h_blkno[unit]++;
                    285:                        htp->htfc = -1;
                    286:                        htp->htcs1 = SREV|GO;
                    287:                        return;
                    288:                }
                    289:                if (state!=SOK) {
                    290:                        bp->b_flags |= B_ERROR;
                    291:                        state = SIO;
                    292:                }
                    293:        } else if (htp->htcs1 < 0) {    /* SC */
                    294:                if(htp->htds & ERR) {
                    295:                        HTMBA->mba_cr &= ~MBAIE;
                    296:                        htp->htcs1 = DCLR|GO;
                    297:                        HTMBA->mba_cr |= MBAIE;
                    298:                }
                    299:        }
                    300:        switch(state) {
                    301:        case SIO:
                    302:        case SOK:
                    303:                h_blkno[unit]++;
                    304: 
                    305:        case SCOM:
                    306:                if(bp == &chtbuf)
                    307:                        if(bp->b_command == SFORW || bp->b_command == SREV)
                    308:                        {
                    309:                                if(bp->b_command == REW)
                    310:                                        h_blkno[unit] -= -bp->b_repcnt;
                    311:                                else
                    312:                                        h_blkno[unit] += -bp->b_repcnt;
                    313:                        } else if(++bp->b_repcnt)
                    314:                                break;
                    315: 
                    316:                httab.b_errcnt = 0;
                    317:                httab.b_actf = bp->av_forw;
                    318:                bp->b_resid = - (htp->htfc & 0xffff);
                    319:                if (bp->b_flags & B_READ)
                    320:                        bp->b_resid += bp->b_bcount;
                    321:                iodone(bp);
                    322:                break;
                    323: 
                    324:        case SRETRY:
                    325:                if((bp->b_flags&B_READ)==0) {
                    326:                        httab.b_active = SSFOR;
                    327:                        htp->htcs1 = ERASE|GO;
                    328:                        return;
                    329:                }
                    330: 
                    331:        case SSFOR:
                    332:        case SSREV:
                    333: #define blk dbtofsb(bp->b_blkno)
                    334:                if(htp->htds & TM) {
                    335:                        if(state == SSREV) {
                    336:                                h_nxrec[unit] = blk - (htp->htfc&0xffff);
                    337:                                h_blkno[unit] = h_nxrec[unit];
                    338:                        } else {
                    339:                                h_nxrec[unit] = blk + (htp->htfc&0xffff) - 1;
                    340:                                h_blkno[unit] = blk + (htp->htfc & 0xffff);
                    341:                        }
                    342:                } else
                    343:                        h_blkno[unit] = blk;
                    344:                break;
                    345: 
                    346:        default:
                    347:                return;
                    348:        }
                    349:        htstart();
                    350: }
                    351: 
                    352: htread(dev)
                    353: {
                    354:        htphys(dev);
                    355:        physio(htstrategy, &rhtbuf, dev, B_READ, minphys);
                    356: }
                    357: 
                    358: htwrite(dev)
                    359: {
                    360:        htphys(dev);
                    361:        physio(htstrategy, &rhtbuf, dev, B_WRITE, minphys);
                    362: }
                    363: 
                    364: htphys(dev)
                    365: {
                    366:        register unit;
                    367:        daddr_t a;
                    368: 
                    369:        unit = minor(dev) & 03;
                    370:        if(unit < NUNIT) {
                    371:                a = u.u_offset >> 9;
                    372:                h_blkno[unit] = dbtofsb(a);
                    373:                h_nxrec[unit] = dbtofsb(a)+1;
                    374:        }
                    375: }
                    376: 
                    377: # define       NHTIOCTRL       (sizeof htiolist)
                    378: 
                    379: char   htiolist[]      =
                    380: {
                    381:        SFORW,          /* 0 = skip forward */
                    382:        SREV,           /* 1 = skip reverse */
                    383:        WEOF,           /* 2 = Write EOF */
                    384:        REW,            /* 3 = rewind */
                    385:        0,              /* 4 = skip forward file */
                    386:        0               /* 5 = skip reverse file */
                    387: };
                    388: 
                    389: htioctrl(dev, cmd, arg, flag)
                    390: register dev_t dev;
                    391: register int cmd, flag, arg;
                    392: {
                    393:        register ioctr;
                    394: 
                    395:        if((unsigned)cmd >= NHTIOCTRL || arg <= 0)
                    396:                u.u_error = ENXIO;
                    397:        else
                    398:        {
                    399:                if(cmd > 3)
                    400:                {
                    401:                        /* Skip forward/reverse file(s) */
                    402:                        cmd -= 3;
                    403:                        ioctr = arg;
                    404:                        arg = -1;
                    405:                }
                    406:                else
                    407:                        ioctr = 1;
                    408:                do
                    409:                        (void) hcommand(dev, htiolist[cmd], arg);
                    410:                while(--ioctr);
                    411:        }
                    412: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.