Annotation of researchv8dc/sys/dev/scn.c, revision 1.1

1.1     ! root        1: /*     scn.c           84/09/05        */
        !             2: 
        !             3: #include "scn.h"
        !             4: #if NSCN > 0
        !             5: /*
        !             6:  * UNIBUS DR11-B driver for teletype scanner
        !             7:  *
        !             8:  */
        !             9: 
        !            10: #include "../h/param.h"
        !            11: #include "../h/systm.h"
        !            12: #include "../h/cpu.h"
        !            13: #include "../h/nexus.h"
        !            14: #include "../h/dk.h"
        !            15: #include "../h/buf.h"
        !            16: #include "../h/conf.h"
        !            17: #include "../h/dir.h"
        !            18: #include "../h/user.h"
        !            19: #include "../h/proc.h"
        !            20: #include "../h/map.h"
        !            21: #include "../h/pte.h"
        !            22: #include "../h/mtpr.h"
        !            23: #include "../h/vm.h"
        !            24: #include "../h/ubavar.h"
        !            25: #include "../h/ubareg.h"
        !            26: #include "../h/cmap.h"
        !            27: 
        !            28: #include "../h/scncmd.h"
        !            29: 
        !            30: struct scndevice{
        !            31:        u_short scn_recvst;     /* receive status register */
        !            32:        u_short scn_recv;       /* receive data register */
        !            33:        u_short scn_sendst;     /* send status register */
        !            34:        u_short scn_send;       /* send data register */
        !            35:        short scnwc;            /* word count reg - unused but load -1 */
        !            36:        u_short scnba;          /* base address reg - must be 16k bdry */
        !            37:        u_short scncs;          /* command/status reg */
        !            38:        u_short scndata;        /* data reg */
        !            39: };
        !            40: struct scnsoftc {
        !            41:        u_short sbmode;         /*select bit mode*/
        !            42:        u_short bpmode;         /* bit pack mode*/
        !            43:        u_short sc_intno;       /* dr11b interrupt number */
        !            44:        int scnreg;             /* index into uba_map */
        !            45:        u_short scn_offset;     /* offset from 16k bdry */
        !            46:        u_int sc_maxi;  /* max interrupt */
        !            47:        caddr_t scnb_addr;
        !            48:        unsigned scn_bdp;
        !            49:        u_short scn_sync;
        !            50: } scnsoftc[NSCN];
        !            51: 
        !            52: #define        SCN_GO  01
        !            53: #define        SCN_IE  0100
        !            54: #define        SCN_NEX 040000
        !            55: #define        SCN_ERROR       0100000
        !            56: 
        !            57: #define SCNSIZE 16384
        !            58: #define SCNPAD 16384
        !            59: #define SCNMASK (SCNPAD-1)
        !            60: #define SCNHSIZE 8192
        !            61: #define SCNHREG 16
        !            62: #define SCNREGMASK     0760
        !            63: #define SCNREST 037777740000
        !            64: 
        !            65: #define SCN_LADDR      037777
        !            66: #define SCN_HADDR      074
        !            67: 
        !            68: int    scnprobe(), scnattach(), scndgo(), scnintr();
        !            69: int    scnstrategy(), scnstart();
        !            70: u_int scnminp();
        !            71: struct uba_ctlr *scnminfo[NSCN];
        !            72: struct uba_device *scndinfo[NSCN];
        !            73: struct uba_ctlr scnctlr[NSCN]; /* scminfo points to this */
        !            74: u_short scnstd[]       = { 0174020, 0};        
        !            75: struct uba_driver scndriver =
        !            76:        { scnprobe,0,scnattach,scndgo,scnstd,"scn",scndinfo,"scn",scnminfo };
        !            77: 
        !            78: #define ui_open        ui_type
        !            79: struct buf     scnbuf[NSCN];
        !            80: struct buf     scnutab[NSCN];
        !            81: 
        !            82: 
        !            83: 
        !            84: 
        !            85: /*ARGSUSED*/
        !            86: scnprobe(reg)
        !            87: caddr_t reg;
        !            88: {
        !            89:        register int br, cvec;  /*int vecs at 310 & 314 */
        !            90:        register struct scndevice *scnaddr = (struct scndevice *) reg;
        !            91:        register short bucket;
        !            92: #ifdef LINT
        !            93:        br = 0; cvec = br; br = cvec;
        !            94: #endif
        !            95: 
        !            96:        scnaddr->scn_recvst = SCN_REC_IE;
        !            97:        scnaddr->scn_send = SCNRS_S;
        !            98:        DELAY(10000);
        !            99:        bucket = scnaddr->scn_recv;     
        !           100:        scnaddr->scn_recvst = 0;
        !           101:        return(1);
        !           102: }
        !           103: 
        !           104: scnattach(ui)
        !           105: register struct uba_device *ui;
        !           106: {
        !           107:        register struct uba_ctlr *um;
        !           108:        register int unit;
        !           109: 
        !           110:        unit = ui->ui_unit;
        !           111: 
        !           112:        um = &scnctlr[unit];
        !           113:        scnminfo[unit] = um;
        !           114:        ui->ui_ctlr = unit;
        !           115:        ui->ui_mi = um;
        !           116:        um->um_driver = ui->ui_driver;
        !           117:        um->um_ctlr = unit;
        !           118:        um->um_ubanum = ui->ui_ubanum;
        !           119:        um->um_alive = 1;
        !           120:        um->um_intr = ui->ui_intr;
        !           121:        um->um_addr = ui->ui_addr;
        !           122:        um->um_hd = ui->ui_hd;
        !           123: }
        !           124: 
        !           125: scnopen(dev)
        !           126: dev_t dev;
        !           127: {
        !           128:        register int unit = minor(dev);
        !           129:        register struct scnsoftc *scnp = &scnsoftc[minor(dev)];
        !           130:        register struct uba_device *ui = scndinfo[unit];
        !           131:        register struct scndevice *draddr = (struct scndevice *)ui->ui_addr;
        !           132: 
        !           133:        if((unit >= NSCN) || (scndinfo[unit]->ui_open)) {
        !           134:                u.u_error = ENXIO;
        !           135:                return;
        !           136:        }
        !           137:        scndinfo[unit]->ui_open++;
        !           138:        draddr->scn_recvst = 0;
        !           139:        scnp->sbmode = SCN_MOD_BW;
        !           140:        scnp->bpmode = 0;
        !           141: }
        !           142: 
        !           143: scnclose(dev)
        !           144: dev_t dev;
        !           145: {
        !           146:        register int unit;
        !           147: 
        !           148:        scndinfo[minor(dev)]->ui_open = 0;
        !           149: }
        !           150: 
        !           151: scnread(dev)
        !           152: dev_t dev;
        !           153: {
        !           154:        register int unit = minor(dev);
        !           155:        physio(scnstrategy,&scnbuf[unit],dev,B_READ,scnminp);
        !           156: 
        !           157: }
        !           158: 
        !           159: scnwrite(dev)
        !           160: dev_t dev;
        !           161: {
        !           162:        register int unit = minor(dev);
        !           163: 
        !           164:        physio(scnstrategy,&scnbuf[unit],dev,B_WRITE,scnminp);
        !           165: }
        !           166: u_int
        !           167: scnminp(bp)
        !           168: struct buf *bp;
        !           169: {
        !           170:        register struct scnsoftc *scnp;
        !           171:        scnp = &scnsoftc[minor(bp->b_dev)];
        !           172:        scnp->sc_maxi = ((bp->b_bcount - SCNPAD)/SCNHSIZE);
        !           173: }
        !           174: 
        !           175: /*
        !           176:  * Due to the fact the scstrategy routine is called only by scnread
        !           177:  * and scnwrite via physio, there will only be one transaction in each
        !           178:  * DR11-B's queue at any time.  Therefore, one can just tack the given
        !           179:  * buffer header pointer on at the end of the queue, and call scstart.
        !           180:  */
        !           181: scnstrategy(bp)
        !           182: register struct buf *bp;
        !           183: {
        !           184:        register struct uba_device *ui;
        !           185:        register struct uba_ctlr *um;
        !           186:        register struct buf *dp;
        !           187:        register int s;
        !           188:        struct scndevice *draddr;
        !           189:        dev_t unit;
        !           190: 
        !           191: 
        !           192:        unit = minor(bp->b_dev);        /* chose a DR11-B */
        !           193:        ui = scndinfo[unit];
        !           194:        um = ui->ui_mi;         /* get ctlr ptr */
        !           195:        dp = &scnutab[unit];
        !           196:        s = spl5();
        !           197:        dp->b_actf = bp;
        !           198:        dp->b_actl = bp;
        !           199:        bp->av_forw = NULL;
        !           200:        um->um_tab.b_actf = dp;
        !           201:        um->um_tab.b_actl = dp;
        !           202:        scnstart(um);
        !           203:        splx(s);        /*dennis says this should go away*/
        !           204:        switch(tsleep((caddr_t)bp, PRIBIO+1, 20)) {
        !           205:        case TS_OK:
        !           206:                break;
        !           207:        case TS_SIG:    /* not supposed to happen*/
        !           208:        case TS_TIME:
        !           209:                draddr = (struct scndevice *)um->um_addr;
        !           210:                bp->b_flags |=  B_ERROR;
        !           211:                s = spl6();     /* if other goes this can to*/
        !           212:                printf("timeout calling scintr\n");
        !           213:                scnintr(unit);
        !           214:                splx(s);        /*likewise this*/
        !           215:        }
        !           216: /*     splx(s);        this is where dennis thinks it should be*/
        !           217: 
        !           218: }
        !           219: 
        !           220: scnstart(um)
        !           221: register struct uba_ctlr *um;
        !           222: {
        !           223:        register struct buf *bp,*dp;
        !           224:        register struct scndevice *draddr;
        !           225:        register struct scnsoftc *scnp;
        !           226:        int cmd;
        !           227: 
        !           228:        dp = um->um_tab.b_actf;
        !           229:        bp = dp->b_actf;
        !           230:        scnp = &scnsoftc[minor(bp->b_dev)];
        !           231: 
        !           232:        scnp->sc_intno = 0;
        !           233:        um->um_tab.b_active++;
        !           234:        draddr = (struct scndevice *)um->um_addr;
        !           235:        draddr->scnwc = -1;
        !           236:        if(bp->b_flags & B_READ)
        !           237:                cmd = SCN_IE;   
        !           238:        else{
        !           239:                u.u_error = EFAULT;
        !           240:        }
        !           241:        um->um_cmd = cmd|SCN_GO;
        !           242:        draddr->scndata = scnp->sbmode|scnp->bpmode|SCN_ARM;
        !           243: 
        !           244:        draddr->scncs = cmd;
        !           245:        bp->b_bcount = SCNSIZE + SCNPAD;
        !           246: 
        !           247:        DELAY(10);
        !           248:        if( ubago(scndinfo[minor(bp->b_dev)])== 0)
        !           249:                printf("ubago returned 0\n");
        !           250: }
        !           251: 
        !           252: scndgo(um)
        !           253: struct uba_ctlr *um;
        !           254: {
        !           255:        register struct scndevice *draddr = (struct scndevice *)um->um_addr;
        !           256:        register unsigned addr, temp;
        !           257:        register struct scnsoftc *scnp;
        !           258:        struct buf *bp, *dp;
        !           259: 
        !           260:        dp = um->um_tab.b_actf;
        !           261:        bp = dp->b_actf;
        !           262:        scnp = &scnsoftc[minor(bp->b_dev)];
        !           263: 
        !           264: /*     temp = bp->b_un.b_addr;*/
        !           265:        addr = um->um_ubinfo;
        !           266:        addr = (addr + (SCNSIZE-1)) & ~(SCNSIZE-1);
        !           267: /*     temp = (temp + (SCNSIZE-1)) & ~(SCNSIZE-1);*/
        !           268:        scnp->scnreg = UBAI_MR(addr);
        !           269:        scnp->scn_offset = (addr - um->um_ubinfo) & (SCNSIZE-1);
        !           270:                                        /* add half so intr can */
        !           271:        scnp->scnb_addr = bp->b_un.b_addr  + SCNHSIZE + scnp->scn_offset;
        !           272:                                                        /*was temp*/
        !           273:        temp = UBAI_BDP(addr);
        !           274:        scnp->scn_bdp = (temp << UBAMR_DPSHIFT) | UBAMR_MRV;
        !           275:        printf("scndgo uminfo %o addr %o reg %o b_addr %o\n",um->um_ubinfo,
        !           276:                addr, scnp->scnreg,bp->b_un.b_addr);
        !           277:        printf("ba %o cs %o scnbaddr %o offset %o\n",(addr&040000),
        !           278:                (um->um_cmd|((addr>>12)&SCN_HADDR)), scnp->scnb_addr,
        !           279:                scnp->scn_offset);
        !           280: 
        !           281:        draddr->scnba = 0;
        !           282:        scnp->scn_sync = 0;
        !           283:        draddr->scncs = um->um_cmd|((addr>>12)&SCN_HADDR);
        !           284:        draddr->scn_recvst |= SCN_REC_IE;
        !           285:        draddr->scn_send = SCN_SCAN;
        !           286: }
        !           287: 
        !           288: scnioctl(dev, cmd, arg)
        !           289: dev_t dev;
        !           290: int cmd;
        !           291: register caddr_t arg;
        !           292: {
        !           293:        register struct scnsoftc *scnp = &scnsoftc[minor(dev)];
        !           294:        register struct uba_device *ui = scndinfo[minor(dev)];
        !           295:        register struct scndevice *draddr = (struct scndevice *)ui->ui_addr;
        !           296:        register struct uba_ctlr *um;
        !           297:        u_short realcmd;
        !           298:        u_short stat;
        !           299:        if( (cmd != SCNRECST) && (cmd != SCNREC) && (cmd != SCNSENDST)
        !           300:                & (cmd != SCNHACK)){
        !           301:                if(copyin(arg, (caddr_t)&realcmd, sizeof(realcmd))){
        !           302:                        u.u_error = EFAULT;
        !           303:                        return;
        !           304:                }
        !           305:        }
        !           306:        switch(cmd){
        !           307:        case SCNSENDST:
        !           308:                realcmd = draddr->scn_sendst;
        !           309:                break;
        !           310:        case SCNSEND:
        !           311:                stat = draddr->scn_sendst;
        !           312:                if(stat & SCN_SREADY)
        !           313:                        draddr->scn_send = realcmd;
        !           314:                else u.u_error = EFAULT;
        !           315:                return;
        !           316:        case SCNRECST:
        !           317:                realcmd = draddr->scn_recvst;
        !           318:                break;
        !           319:        case SCNREC:
        !           320:                realcmd = draddr->scn_recv;
        !           321:                break;
        !           322:        case SCNHACK:
        !           323:                realcmd = scnp->scn_offset;
        !           324:                break;
        !           325:        case SCNSBMOD:
        !           326:                scnp->sbmode = realcmd & SCN_SBMASK;
        !           327:                return;
        !           328:        case SCNBPMOD:
        !           329:                scnp->bpmode = realcmd & SCN_BPMASK;
        !           330:                return;
        !           331:        default:
        !           332:                u.u_error = ENXIO;
        !           333:                return;
        !           334:        }
        !           335:        if(copyout((caddr_t)&realcmd, arg, sizeof(realcmd)))
        !           336:                u.u_error = EFAULT;
        !           337: }
        !           338: scnreset() {}
        !           339: 
        !           340: scnxintr(dr11)
        !           341: register dr11;
        !           342: {
        !           343:        register struct scndevice *draddr;
        !           344:        register struct uba_ctlr *um;
        !           345:        struct buf *dp, *bp;
        !           346:        register int stat;
        !           347:        struct scnsoftc *scnp;
        !           348: 
        !           349:        um = scnminfo[dr11];
        !           350:        draddr = (struct scndevice *)um->um_addr;
        !           351: 
        !           352:        stat = draddr->scn_recv;
        !           353:        if(stat == SCN_STATE2){
        !           354:                draddr->scn_send = SCN_WAIT;
        !           355:                return;
        !           356:        }
        !           357:        if(stat == SCN_STATE3){
        !           358:                scnp = &scnsoftc[minor(dr11)];
        !           359:                printf("got ack state 3:intno %o max %o\n", scnp->sc_intno,scnp->sc_maxi);
        !           360:                dp = um->um_tab.b_actf;
        !           361:                bp= dp->b_actf;
        !           362:                draddr->scndata = 0;
        !           363:                draddr->scn_recvst = 0;
        !           364:                draddr->scncs = 0;
        !           365:                um->um_tab.b_active = 0;
        !           366:                um->um_tab.b_errcnt = 0;
        !           367:                um->um_tab.b_actf = dp->b_forw;
        !           368:                dp->b_errcnt = 0;
        !           369:                dp->b_active = 0;
        !           370:                bp->b_resid = 0;
        !           371:                ubadone(um);
        !           372:                iodone(bp);
        !           373:                return;
        !           374:        }
        !           375:        return;
        !           376: }
        !           377: 
        !           378: scnintr(dr11)
        !           379: register dr11;
        !           380: {
        !           381:        register struct buf *bp,*dp;
        !           382:        register struct scndevice *draddr;
        !           383:        register struct uba_ctlr *um;
        !           384:        register unsigned stat, reg,temp;
        !           385:        u_short bit;
        !           386:        struct pte *io, *pte;
        !           387:        struct scnsoftc *scnp;
        !           388: 
        !           389:        um = scnminfo[dr11];
        !           390:        scnp = &scnsoftc[dr11];
        !           391: 
        !           392:        if(um->um_tab.b_active == 0)
        !           393:                return;
        !           394: 
        !           395:        if(scndinfo[dr11]->ui_open == 0)
        !           396:                return;
        !           397:        dp = um->um_tab.b_actf;
        !           398:        bp = dp->b_actf;
        !           399:        draddr = (struct scndevice *)um->um_addr;
        !           400:        stat = draddr->scncs;
        !           401:        if(stat & SCN_ERROR){
        !           402:                reg = draddr->scnba;
        !           403:                printf("scanner error %o addr %o intno %d\n",stat,
        !           404:                        reg,scnp->sc_intno);
        !           405:                goto scbad;
        !           406:        }
        !           407:        if(scnp->sc_intno >= scnp->sc_maxi){
        !           408:                printf("quiting on maxi %o\n",scnp->sc_intno);
        !           409:                goto scbad;
        !           410:        }
        !           411:        bit = draddr->scnba & 020000;
        !           412:        if(scnp->scn_sync == bit)
        !           413:                printf("scn out of sync %d addr=%o\n",
        !           414:                        scnp->sc_intno,draddr->scnba);
        !           415:        scnp->scn_sync = bit;
        !           416:        reg = scnp->scnreg;
        !           417:        if(scnp->sc_intno++ & 01)
        !           418:                reg += SCNHREG;
        !           419:        scnp->scnb_addr += SCNHSIZE;
        !           420: 
        !           421:        stat = btop(scnp->scnb_addr);
        !           422:        pte = vtopte(bp->b_proc, stat);
        !           423:        
        !           424:        io = &um->um_hd->uh_uba->uba_map[reg];
        !           425:        stat = SCNHREG;
        !           426:        temp = scnp->scn_bdp;
        !           427:        while(stat-- > 0){
        !           428:                if(pte->pg_pfnum == 0){
        !           429:                        printf("about to write to 0 pte int %o stat %d\n",
        !           430:                                scnp->sc_intno,stat);
        !           431:                        goto scbad;
        !           432:                }
        !           433:                *(int *)io++ = pte++->pg_pfnum | temp;
        !           434:        }
        !           435:        return;
        !           436: 
        !           437: scbad:
        !           438:        draddr->scndata = 0;    /*turn off arm bit*/
        !           439:        draddr->scn_recvst = 0; /*turn off recv intr*/
        !           440:        draddr->scncs = 0;      /*turn off scn intr*/
        !           441:        um->um_tab.b_active = 0;
        !           442:        um->um_tab.b_errcnt = 0;
        !           443:        um->um_tab.b_actf = dp->b_forw;
        !           444:        dp->b_errcnt = 0;
        !           445:        dp->b_active = 0;
        !           446:        bp->b_resid = 0;
        !           447:        ubadone(um);
        !           448:        iodone(bp);
        !           449: 
        !           450: }
        !           451: #endif

unix.superglobalmegacorp.com

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