Annotation of researchv10no/sys/io/ta.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * DSA tape class driver
                      3:  * drives TMSCP tapes
                      4:  */
                      5: 
                      6: #include "sys/param.h"
                      7: #include "sys/buf.h"
                      8: #include "sys/ta.h"
                      9: #include "sys/mscp.h"
                     10: #include "sys/user.h"
                     11: #include "sys/file.h"
                     12: #include "sys/conf.h"
                     13: #include "sys/mtio.h"
                     14: 
                     15: extern struct msaddr taaddr[];
                     16: extern struct tatape tatape[];
                     17: extern int tacnt;
                     18: static long tarefno;                   /* ref seq num */
                     19: extern struct buf tabuf[];
                     20: 
                     21: static tacmd(), taonline(), tasonl(), tacinit();
                     22: 
                     23: int taopen(), taread(), tawrite(), taioctl(), tastrategy(), taclose();
                     24: struct bdevsw tabdev = bdinit(taopen, taclose, tastrategy, B_TAPE);
                     25: struct cdevsw tacdev = cdinit(taopen, taclose, taread, tawrite, taioctl);
                     26: 
                     27: /*
                     28:  * minor device number split
                     29:  *
                     30:  * NOCACHE disables write-behind caching; probably useless
                     31:  * DENS selects one of the eight TMSCP density values;
                     32:  * the drive is instructed to use 1<<DENS(dev) in whatever
                     33:  * density language it believes
                     34:  * here are some languages:
                     35:  * for 9-track tapes, (0) 800 bpi (1) PE (2) GCR
                     36:  * for old cartridge tapes (TK50), (3) block tape
                     37:  * for new cartridge tapes (TK70), (0) low density (1) high density
                     38:  * for other TMSCP devices, (0) is usually the right number
                     39:  */
                     40: #define        UNIT(d) ((d)&07)
                     41: #define        DENS(d) (((d)&070)>>3)
                     42: #define        NOCACHE(d) ((d)&0100)
                     43: #define        NOREW(d) ((d)&0200)
                     44: 
                     45: /*
                     46:  * reused bits of buf/iobuf struct
                     47:  */
                     48: 
                     49: #define        b_next  av_forw         /* next buffer in queue */
                     50: #define        b_pkt   av_back         /* pointer to mscp command */
                     51: #define        b_crf   b_resid         /* saved refno for pending command */
                     52: 
                     53: /*
                     54:  * flags in tatape.flags
                     55:  */
                     56: 
                     57: #define        ONLINE  01              /* drive is online */
                     58: #define        WONLINE 02              /* waiting for online */
                     59: #define        OPEN    04              /* someone has drive open */
                     60: #define        WRITTEN 010             /* some data was written */
                     61: #define        WPROT   020             /* drive is write protected */
                     62: #define        NEEDCMD 040             /* waiting for some command to start */
                     63: #define        CMDDONE 0100            /* command is finished */
                     64: #define        CMDERR  0200            /* command finished, and error */
                     65: #define        UNHAPPY 0400            /* needs `cache data loss' clear */
                     66: #define        WONLY   01000           /* tape was opened only for writing */
                     67: 
                     68: /*
                     69:  * random numbers
                     70:  */
                     71: 
                     72: #define        PRIONL  (PZERO-1)
                     73: #define        IDTA    1               /* connection ID for MSCP */
                     74: 
                     75: /*
                     76:  * open a drive
                     77:  */
                     78: 
                     79: int taseql(), tadg();
                     80: 
                     81: taopen(dev, flag)
                     82: dev_t dev;
                     83: {
                     84:        register int unit;
                     85:        register struct tatape *ta;
                     86:        register struct msaddr *rp;
                     87:        int wasoff;
                     88: 
                     89:        unit = UNIT(dev);
                     90:        if (unit > tacnt) {
                     91:                u.u_error = ENXIO;
                     92:                return;
                     93:        }
                     94:        ta = &tatape[unit];
                     95:        rp = &taaddr[unit];
                     96:        if (ta->flags & OPEN) {
                     97:                u.u_error = EBUSY;
                     98:                return;
                     99:        }
                    100:        if (rp->ctype < 0 || rp->ctype >= nmsport
                    101:        ||  (ta->port = msportsw[rp->ctype]) == NULL) {
                    102:                u.u_error = ENXIO;
                    103:                return;
                    104:        }
                    105:        ta->flags |= OPEN;
                    106:        ta->flags &=~ (WRITTEN|WPROT|WONLY);
                    107:        if ((*ta->port->mp_init)(rp->ctl, rp->ctype, 0, IDTA, taseql, tadg) == 0) {
                    108:                u.u_error = ENXIO;
                    109:                ta->flags &=~ OPEN;
                    110:                return;
                    111:        }
                    112:        tacinit(ta, rp);
                    113:        spl6();
                    114:        wasoff = (ta->flags & ONLINE) == 0;
                    115:        if ((ta->flags & ONLINE) == 0)
                    116:                taonline(ta, rp);
                    117:        spl0();
                    118:        if ((ta->flags & ONLINE) == 0) {
                    119:                u.u_error = ENXIO;
                    120:                ta->flags &=~ OPEN;
                    121:                return;
                    122:        }
                    123:        if ((ta->flags & WPROT) && (flag & FWRITE)) {
                    124:                u.u_error = ENODEV;
                    125:                if (!NOREW(dev))
                    126:                        tacmd(unit, 1, OPAVL, 0, 0);
                    127:                ta->flags &=~ (OPEN|ONLINE);
                    128:                return;
                    129:        }
                    130:        ta->dens = (1<<DENS(dev));
                    131:        if (tacmd(unit, 0, OPGUS, 0, 0)         /* fill in language in dens */
                    132:        ||  tacmd(unit, 0, OPSUC, NOCACHE(dev)?0:UFWBK, wasoff?ta->dens:0)) {
                    133:                u.u_error = ENXIO;
                    134:                if (!NOREW(dev))
                    135:                        tacmd(unit, 1, OPAVL, 0, 0);
                    136:                ta->flags &=~ (OPEN|ONLINE);
                    137:                return;
                    138:        }
                    139:        if ((flag & (FREAD|FWRITE)) == FWRITE)
                    140:                ta->flags |= WONLY;
                    141: }
                    142: 
                    143: taclose(dev)
                    144: {
                    145:        register struct tatape *ta;
                    146:        int unit;
                    147: 
                    148:        unit = UNIT(dev);
                    149:        ta = &tatape[unit];
                    150:        if (ta->flags & ONLINE) {
                    151:                if (ta->flags & (WONLY|WRITTEN)) {
                    152:                        tacmd(unit, 0, OPWRM, 0, 0);
                    153:                        tacmd(unit, 0, OPWRM, 0, 0);
                    154:                        tacmd(unit, 0, OPPOS, 0, -1);
                    155:                }
                    156:                /* annoyance: OPAVL always rewinds. */
                    157:                if (!NOREW(dev))
                    158:                        tacmd(unit, 1, OPAVL, 0, 0);
                    159:        }
                    160:        ta->flags &=~ OPEN;
                    161: }
                    162: 
                    163: /*
                    164:  * send some non-io command to a tape drive
                    165:  * op is the MSCP opcode;
                    166:  * p0 and p1 are some parameters
                    167:  * if async == 0, don't return until command does
                    168:  */
                    169: 
                    170: #define        TWPRI   PZERO
                    171: #define        TCPRI   (PZERO+1)
                    172: 
                    173: static
                    174: tacmd(dev, async, op, p0, p1)
                    175: {
                    176:        register struct mscmd *mp;
                    177:        register struct tatape *ta;
                    178:        register struct msaddr *rp;
                    179:        register s;
                    180:        register err;
                    181: 
                    182:        ta = &tatape[dev];
                    183:        rp = &taaddr[dev];
                    184:        if ((ta->flags & ONLINE) == 0)
                    185:                return (1);
                    186:        mp = (*ta->port->mp_get)(rp->ctl);
                    187:        bzero((caddr_t)mp, sizeof(struct mscmd)); /* clear reserved fields */
                    188:        mp->m_crf = ++tarefno;
                    189:        mp->m_unit = rp->unit;
                    190:        mp->m_opcd = op;
                    191:        mp->m_mod = MDCSX;
                    192:        switch (op) {
                    193:        case OPPOS:             /* position: type, nobjs */
                    194:                if (p1 < 0) {
                    195:                        p1 = -p1;
                    196:                        mp->m_mod |= MDREV;
                    197:                }
                    198:                if (p0 == -1) {         /* -1 == rewind */
                    199:                        mp->m_mod |= MDREW;
                    200:                        mp->m_mod |= p1;        /* hack */
                    201:                }
                    202:                else if (p0 == 0)       /* 0 == skip files */
                    203:                        mp->m_fcnt = p1;
                    204:                else {                  /* 1 == skip records */
                    205:                        mp->m_mod |= MDOBJ;
                    206:                        mp->m_rcnt = p1;
                    207:                }
                    208:                break;
                    209: 
                    210:        case OPSUC:             /* set unit char: unit flags, density */
                    211:                mp->m_unfl |= p0;
                    212:                mp->m_fmt = p1;
                    213:                break;
                    214: 
                    215:        case OPGUS:             /* get unit status */
                    216:                mp->m_mod = p0; /* wretched TK50 */
                    217:                break;
                    218: 
                    219:        default:                /* anything else: modifiers, 0 */
                    220:                mp->m_mod |= p0;
                    221:                break;
                    222:        }
                    223:        s = spl6();
                    224:        while (ta->cmdp) {
                    225:                ta->flags |= NEEDCMD;
                    226:                sleep((caddr_t)ta, TWPRI);
                    227:        }
                    228:        ta->cmdp = mp;
                    229:        ta->flags &=~ (CMDERR|CMDDONE);
                    230:        if (ta->flags & UNHAPPY) {
                    231:                ta->flags &=~ UNHAPPY;
                    232:                mp->m_mod |= MDCDL;
                    233:        }
                    234:        (*ta->port->mp_send)(rp->ctl, IDTA, mp);
                    235:        if (async == 0) {
                    236:                while ((ta->flags & CMDDONE) == 0)
                    237:                        if (tsleep((caddr_t)ta, TCPRI, 0) == TS_SIG)
                    238:                                break;
                    239:        }
                    240:        err = ((ta->flags & CMDERR) != 0);
                    241:        ta->cmdp = NULL;
                    242:        if (ta->flags & NEEDCMD) {
                    243:                ta->flags &=~ NEEDCMD;
                    244:                wakeup((caddr_t)ta);
                    245:        }
                    246:        splx(s);
                    247:        return (err);
                    248: }
                    249: 
                    250: int tastrategy();
                    251: 
                    252: taread(dev)
                    253: {
                    254:        physio(tastrategy, &tabuf[UNIT(dev)], dev, B_READ, minphys);
                    255: }
                    256: 
                    257: tawrite(dev)
                    258: {
                    259:        physio(tastrategy, &tabuf[UNIT(dev)], dev, B_WRITE, minphys);
                    260: }
                    261: 
                    262: /*
                    263:  * strategy routine;
                    264:  * send the packet right away
                    265:  */
                    266: 
                    267: tastrategy(bp)
                    268: register struct buf *bp;
                    269: {
                    270:        register struct tatape *ta;
                    271:        register struct mscmd *mp;
                    272:        register int unit;
                    273:        register struct msaddr *rp;
                    274:        int count;
                    275: 
                    276:        unit = UNIT(minor(bp->b_dev));
                    277:        ta = &tatape[unit];
                    278:        rp = &taaddr[unit];
                    279:        count = bp->b_bcount;
                    280:        spl6();
                    281:        if ((ta->flags & ONLINE) == 0 && taonline(ta, rp) == 0) {
                    282:                bp->b_flags |= B_ERROR;
                    283:                iodone(bp);
                    284:                spl0();
                    285:                return;
                    286:        }
                    287:        mp = (*ta->port->mp_get)(rp->ctl);
                    288:        mp->m_crf = ++tarefno;
                    289:        mp->m_unit = rp->unit;
                    290:        mp->m_opcd = (bp->b_flags & B_READ) ? OPRD : OPWR;
                    291:        mp->m_mod = MDCSX;
                    292:        if (ta->flags & UNHAPPY && (bp->b_flags & B_READ) == 0) {
                    293:                ta->flags &=~ UNHAPPY;
                    294:                mp->m_mod |= MDCDL;
                    295:        }
                    296:        mp->m_unfl = 0;
                    297:        mp->m_bcnt = count;
                    298:        /* seek on block device? later */
                    299:        (*ta->port->mp_map)(rp->ctl, mp, bp);
                    300:        bp->b_pkt = (struct buf *)mp;
                    301:        bp->b_crf = mp->m_crf;
                    302:        bp->b_next = NULL;
                    303:        if (ta->actf)
                    304:                ta->actl->b_next = bp;
                    305:        else
                    306:                ta->actf = bp;
                    307:        ta->actl = bp;
                    308:        if ((bp->b_flags & B_READ) == 0)
                    309:                ta->flags |= WRITTEN;
                    310:        (*ta->port->mp_send)(rp->ctl, IDTA, mp);
                    311:        spl0();
                    312: }
                    313: 
                    314: /*
                    315:  * ioctl
                    316:  * a subset of the berkeley ones
                    317:  */
                    318: 
                    319: taioctl(dev, cmd, addr, flag)
                    320: dev_t dev;
                    321: caddr_t addr;
                    322: {
                    323:        struct mtop mt;
                    324:        int func, p0, p1;
                    325: 
                    326:        switch (cmd) {
                    327:        default:
                    328:                u.u_error = ENOTTY;
                    329:                break;
                    330:        /* does anything use the other ones? */
                    331: 
                    332:        case MTIOCTOP:
                    333:                if (copyin(addr, (caddr_t)&mt, sizeof(struct mtop)) < 0) {
                    334:                        u.u_error = EFAULT;
                    335:                        return;
                    336:                }
                    337:                if (mt.mt_op == MTWEOF) {       /* oddball */
                    338:                        if ((flag & FWRITE) == 0) {
                    339:                                u.u_error = EBADF;
                    340:                                return;
                    341:                        }
                    342:                        while (mt.mt_count-- > 0)
                    343:                                if (tacmd(UNIT(dev), 0, OPWRM, 0, 0)) {
                    344:                                        u.u_error = EIO;
                    345:                                        return;
                    346:                                }
                    347:                        return;
                    348:                }
                    349:                if (mt.mt_op == MTRST) {        /* another oddball */
                    350:                        (*tatape[UNIT(dev)].port->mp_init)(taaddr[UNIT(dev)].ctl, taaddr[UNIT(dev)].ctype, 1, IDTA, taseql, tadg);
                    351:                        return;
                    352:                }
                    353:                p1 = mt.mt_count;
                    354:                func = OPPOS;
                    355:                switch (mt.mt_op) {     /* arcane arguments to tapos */
                    356:                case MTBSF:
                    357:                        p1 = -p1;
                    358:                case MTFSF:
                    359:                        p0 = 0;
                    360:                        break;
                    361: 
                    362:                case MTBSR:
                    363:                        p1 = -p1;
                    364:                case MTFSR:
                    365:                        p0 = 1;
                    366:                        break;
                    367: 
                    368:                case MTREW:
                    369:                        p1 = 0;
                    370:                        p0 = -1;
                    371:                        break;
                    372: 
                    373:                case MTOFFL:
                    374:                        func = OPAVL;
                    375:                        p1 = 0;
                    376:                        p0 = MDUNL;
                    377:                        break;
                    378: 
                    379:                case MTNOP:
                    380:                        return; /* silly */
                    381:                }
                    382:                if (tacmd(UNIT(dev), 0, func, p0, p1))
                    383:                        u.u_error = EIO;
                    384:                break;
                    385:        }
                    386: }
                    387: 
                    388: /*
                    389:  * here when the port gets a sequential message
                    390:  */
                    391: taseql(ctl, type, ep)
                    392: int ctl, type;
                    393: register struct msend *ep;
                    394: {
                    395:        register struct buf *bp;
                    396:        register struct tatape *ta;
                    397:        register int unit;
                    398:        register struct buf *obp;
                    399:        int sts;
                    400: 
                    401:        if (ep->m_opcd == 0 && ep->m_sts == STRST) {
                    402:                tareset(ctl, type);
                    403:                return;
                    404:        }
                    405:        /* get rid of this wretched loop somehow */
                    406:        for (unit = 0; unit < tacnt; unit++)
                    407:                if (taaddr[unit].ctl == ctl
                    408:                &&  taaddr[unit].ctype == type
                    409:                &&  taaddr[unit].unit == ep->m_unit)
                    410:                        break;
                    411:        if (unit >= tacnt) {
                    412:                printf("tmscp stray unit: ctl%d typ%d ta%d sts %o opcode %o\n",
                    413:                        ctl, type, ep->m_unit, ep->m_sts, ep->m_opcd);
                    414:                return;
                    415:        }
                    416:        ta = &tatape[unit];
                    417:        if (ep->m_flgs & EFCDL)
                    418:                ta->flags |= UNHAPPY;
                    419:        switch (ep->m_opcd & 0377) {
                    420:        case OPEND:             /* eg invalid command */
                    421:                printf("tmscp ctl%d ta%d ill cmd crf %d off %d\n", ctl,
                    422:                        ep->m_unit, ep->m_crf, ep->m_sts>>8);
                    423:                if (ta->cmdp && ta->cmdp->m_crf == ep->m_crf)
                    424:                        goto fincmd;
                    425:                /* else maybe it's a transfer; fall in */
                    426:        case OPRD|OPEND:
                    427:        case OPWR|OPEND:
                    428:                for (bp = ta->actf, obp = NULL; bp; obp = bp, bp = bp->b_next)
                    429:                        if (ep->m_crf == bp->b_crf)
                    430:                                break;
                    431:                if (bp == NULL) {
                    432:                        printf("ta%d stray end: crf %d sts x%x opcode 0%o\n",
                    433:                                unit, ep->m_crf, ep->m_sts, ep->m_opcd & 0377);
                    434:                        return;
                    435:                }
                    436:                if (obp)
                    437:                        obp->b_next = bp->b_next;
                    438:                else
                    439:                        ta->actf = bp->b_next;
                    440:                if (bp == ta->actl)
                    441:                        ta->actl = obp;
                    442:                sts = ep->m_sts & STMSK;
                    443:                if (sts == STAVL || sts == STOFL)
                    444:                        ta->flags &=~ ONLINE;   /* help! */
                    445:                bp->b_resid = bp->b_bcount - ep->m_bcnt;
                    446:                if (sts == STTPM)
                    447:                        sts = STSUC;    /* tape mark -> empty read */
                    448:                if (sts != STSUC) {
                    449:                        bp->b_flags |= B_ERROR;
                    450:                        switch (sts) {
                    451:                        case STRDT:
                    452:                        case STOFL:
                    453:                        case STAVL:
                    454:                        case STWPR:     /* well ... */
                    455:                                break;
                    456:                        default:
                    457:                                printf("err on ta%d block %D: sts 0%o flgs 0%o\n", unit, bp->b_blkno, ep->m_sts, ep->m_flgs);
                    458:                        }
                    459:                }
                    460:                if (ep->m_flgs & EFEOT && (bp->b_flags & B_READ) == 0) {
                    461:                        bp->b_error = ENOSPC;
                    462:                        bp->b_flags |= B_ERROR;
                    463:                }
                    464:                (*ta->port->mp_unmap)(ctl, (struct mscmd *)bp->b_pkt);
                    465:                iodone(bp);
                    466:                return;
                    467: 
                    468:        case OPGUS|OPEND:
                    469:                ta->dens &= TFMASK;
                    470:                ta->dens |= ep->m_menu & ~TFMASK;
                    471:                goto fincmd;
                    472: 
                    473:        case OPAVL|OPEND:
                    474:                if (ep->m_sts == STSUC) /* sic */
                    475:                        ta->flags &=~ ONLINE;
                    476:        case OPWRM|OPEND:
                    477:        case OPPOS|OPEND:
                    478:        case OPFLS|OPEND:
                    479:        case OPSUC|OPEND:
                    480:        fincmd:
                    481:                if ((ep->m_sts & STMSK) == STAVL || (ep->m_sts & STMSK) == STOFL)
                    482:                        ta->flags &=~ ONLINE;
                    483:                if (ta->cmdp) {
                    484:                        ta->flags |= CMDDONE;
                    485:                        if ((ep->m_sts & STMSK) != STSUC) {
                    486:                                printf("ta%d: cmd 0%o sts 0%o flgs 0%o\n", unit, ep->m_opcd&0377, ep->m_sts, ep->m_flgs);
                    487:                                ta->flags |= CMDERR;
                    488:                        }
                    489:                        wakeup((caddr_t)ta);
                    490:                }
                    491:                return;
                    492: 
                    493:        case OPONL|OPEND:
                    494:                tasonl(ta, ep);
                    495:                return;
                    496: 
                    497:        case OPSCC|OPEND:
                    498:                if ((ep->m_sts & STMSK) != STSUC)
                    499:                        printf("tmscp ctl%d typ%d: bad init\n", ctl, type);
                    500:                return;
                    501: 
                    502:        default:
                    503:                printf("stray tmscp msg ta%d opcd 0%o sts x%x\n",
                    504:                        unit, ep->m_opcd&0377, ep->m_sts&0177777);
                    505:                return;
                    506:        }
                    507: }
                    508: 
                    509: /*
                    510:  * controller was reset
                    511:  * discard all pending io,
                    512:  * awake all sleepers,
                    513:  * mark everything offline
                    514:  */
                    515: 
                    516: tareset(ctl, type)
                    517: int ctl, type;
                    518: {
                    519:        register int unit;
                    520:        register struct tatape *ta;
                    521:        register struct buf *bp, *nbp;
                    522: 
                    523:        for (unit = 0; unit < tacnt; unit++)  {
                    524:                if (taaddr[unit].ctl != ctl || taaddr[unit].ctype != type)
                    525:                        continue;
                    526:                ta = &tatape[unit];
                    527:                for (bp = ta->actf; bp; bp = nbp) {
                    528:                        nbp = bp->b_next;
                    529:                        (*ta->port->mp_unmap)(ctl, (struct mscmd *)bp->b_pkt);
                    530:                        bp->b_flags |= B_ERROR;
                    531:                        iodone(bp);
                    532:                }
                    533:                ta->actf = ta->actl = NULL;
                    534:                ta->flags &=~ (ONLINE|WONLINE);
                    535:                if (ta->cmdp)
                    536:                        ta->flags |= CMDDONE|CMDERR;
                    537:                wakeup((caddr_t)ta);
                    538:        }
                    539: }
                    540: 
                    541: /*
                    542:  * here with a datagram message
                    543:  * explanations really shouldn't be in the driver
                    544:  */
                    545: 
                    546: static char *taevents[] = {
                    547:        "ok",
                    548:        "inv cmd",
                    549:        "op aborted",
                    550:        "offline",
                    551:        "available",
                    552:        "med fmt",
                    553:        "write prot",
                    554:        "comp err",
                    555:        "data err",
                    556:        "host buf access err",
                    557:        "cntl err",
                    558:        "drive err",
                    559: };
                    560: #define        MAXEVT  0xb
                    561: 
                    562: tadg(ctl, type, ep)
                    563: int ctl, type;
                    564: register struct mserl *ep;
                    565: {
                    566: 
                    567:        if (ep->l_evnt == STSEX)        /* boring, at least for now */
                    568:                return;
                    569:        printf("ta%d ctl%d typ%d seq %d: %s err; fmt x%x ev x%x fl x%x\n",
                    570:                ep->l_unit, ctl, type, ep->l_seq,       /* phys unit, not log */
                    571:                ep->l_flgs&(LFSUC|LFCON) ? "soft" : "hard",
                    572:                ep->l_fmt, ep->l_evnt, ep->l_flgs&0377);
                    573:        if ((ep->l_evnt & STMSK) <= MAXEVT)
                    574:                printf("%s; ", taevents[ep->l_evnt & STMSK]);
                    575:        switch (ep->l_fmt) {
                    576:        case FMCNT:
                    577:                /* now the thing should be marked disastrously bad */
                    578:                printf("oops\n");
                    579:                break;
                    580: 
                    581:        case FMBAD:
                    582:                printf("host mem access; addr x%x\n", ep->l_badr);
                    583:                break;
                    584: 
                    585:        case FMTAPE:
                    586:                printf("lvl x%x retry x%x\n", ep->l_lvl, ep->l_rtry);
                    587:                break;
                    588: 
                    589:        default:
                    590:                printf("\n");
                    591:                break;
                    592:        }
                    593: }
                    594: 
                    595: /*
                    596:  * unit is believed offline
                    597:  * try to bring it on
                    598:  */
                    599: 
                    600: static
                    601: taonline(ta, rp)
                    602: register struct tatape *ta;
                    603: register struct msaddr *rp;
                    604: {
                    605:        register struct mscmd *mp;
                    606:        int s;
                    607: 
                    608:        s = spl6();
                    609:        if ((ta->flags & WONLINE) == 0) {
                    610:                mp = (*ta->port->mp_get)(rp->ctl);
                    611:                bzero((caddr_t)mp, sizeof(struct mscmd)); /* clear reserved fields */
                    612:                mp->m_crf = ++tarefno;
                    613:                mp->m_unit = rp->unit;
                    614:                mp->m_opcd = OPONL;
                    615:                mp->m_mod = MDCSX|MDXCL;
                    616:                if (ta->flags & UNHAPPY) {
                    617:                        ta->flags &=~ UNHAPPY;
                    618:                        mp->m_mod |= MDCDL;
                    619:                }
                    620:                mp->m_unfl = 0;
                    621:                mp->m_fmt = 0;  /* ta->dens? */
                    622:                (*ta->port->mp_send)(rp->ctl, IDTA, mp);
                    623:                ta->flags |= WONLINE;
                    624:        }
                    625:        while (ta->flags & WONLINE)
                    626:                tsleep((caddr_t)ta, PRIONL, 60);
                    627:        splx(s);
                    628:        if ((ta->flags & ONLINE) == 0)
                    629:                return (0);
                    630:        return (1);
                    631: }
                    632: 
                    633: static
                    634: tasonl(ta, ep)
                    635: register struct tatape *ta;
                    636: register struct msend *ep;
                    637: {
                    638: 
                    639:        if (ta->flags & WONLINE) {
                    640:                ta->flags &=~ WONLINE;
                    641:                wakeup((caddr_t)ta);
                    642:        }
                    643:        if ((ep->m_sts & STMSK) != STSUC)
                    644:                return;
                    645:        ta->flags |= ONLINE;
                    646:        if (ep->m_unfl & UFWPH)
                    647:                ta->flags |= WPROT;
                    648: }
                    649: 
                    650: /*
                    651:  * controller init
                    652:  * set characteristics to turn off host timeouts
                    653:  */
                    654: 
                    655: static
                    656: tacinit(ta, rp)
                    657: struct tatape *ta;
                    658: struct msaddr *rp;
                    659: {
                    660:        register struct mscmd *mp;
                    661:        register int s;
                    662: 
                    663:        mp = (*ta->port->mp_get)(rp->ctl);
                    664:        bzero((caddr_t)mp, sizeof(struct mscmd)); /* clear reserved fields */
                    665:        mp->m_crf = ++tarefno;
                    666:        mp->m_opcd = OPSCC;
                    667:        mp->m_mod = MDCSX;
                    668:        mp->m_cntf = CFMSC | CFTHS;
                    669:        mp->m_vrsn = MSCPVER;
                    670:        s = spl6();
                    671:        (*ta->port->mp_send)(rp->ctl, IDTA, mp);
                    672:        splx(s);
                    673: }

unix.superglobalmegacorp.com

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