Annotation of lucent/sys/src/9/gnot/devduart.c, revision 1.1

1.1     ! root        1: #include       "u.h"
        !             2: #include       "../port/lib.h"
        !             3: #include       "mem.h"
        !             4: #include       "dat.h"
        !             5: #include       "fns.h"
        !             6: #include       "io.h"
        !             7: #include       "ureg.h"
        !             8: #include       "../port/error.h"
        !             9: 
        !            10: #include       "devtab.h"
        !            11: 
        !            12: int    duartacr;
        !            13: int    duartimr;
        !            14: void   (*kprofp)(ulong);
        !            15: 
        !            16: /*
        !            17:  * Register set for half the duart.  There are really two sets.
        !            18:  */
        !            19: struct Duart{
        !            20:        uchar   mr1_2;          /* Mode Register Channels 1 & 2 */
        !            21:        uchar   sr_csr;         /* Status Register/Clock Select Register */
        !            22:        uchar   cmnd;           /* Command Register */
        !            23:        uchar   data;           /* RX Holding / TX Holding Register */
        !            24:        uchar   ipc_acr;        /* Input Port Change/Aux. Control Register */
        !            25: #define        ivr     ivr             /* Interrupt Vector Register */
        !            26:        uchar   is_imr;         /* Interrupt Status/Interrupt Mask Register */
        !            27: #define        ip_opcr is_imr          /* Input Port/Output Port Configuration Register */
        !            28:        uchar   ctur;           /* Counter/Timer Upper Register */
        !            29: #define        scc_sopbc ctur          /* Start Counter Command/Set Output Port Bits Command */
        !            30:        uchar   ctlr;           /* Counter/Timer Lower Register */
        !            31: #define        scc_ropbc ctlr          /* Stop Counter Command/Reset Output Port Bits Command */
        !            32: };
        !            33: 
        !            34: enum{
        !            35:        CHAR_ERR        =0x00,  /* MR1x - Mode Register 1 */
        !            36:        PAR_ENB         =0x00,
        !            37:        EVEN_PAR        =0x00,
        !            38:        ODD_PAR         =0x04,
        !            39:        NO_PAR          =0x10,
        !            40:        CBITS8          =0x03,
        !            41:        CBITS7          =0x02,
        !            42:        CBITS6          =0x01,
        !            43:        CBITS5          =0x00,
        !            44:        NORM_OP         =0x00,  /* MR2x - Mode Register 2 */
        !            45:        TWOSTOPB        =0x0F,
        !            46:        ONESTOPB        =0x07,
        !            47:        ENB_RX          =0x01,  /* CRx - Command Register */
        !            48:        DIS_RX          =0x02,
        !            49:        ENB_TX          =0x04,
        !            50:        DIS_TX          =0x08,
        !            51:        RESET_MR        =0x10,
        !            52:        RESET_RCV       =0x20,
        !            53:        RESET_TRANS     =0x30,
        !            54:        RESET_ERR       =0x40,
        !            55:        RESET_BCH       =0x50,
        !            56:        STRT_BRK        =0x60,
        !            57:        STOP_BRK        =0x70,
        !            58:        RCV_RDY         =0x01,  /* SRx - Channel Status Register */
        !            59:        FIFOFULL        =0x02,
        !            60:        XMT_RDY         =0x04,
        !            61:        XMT_EMT         =0x08,
        !            62:        OVR_ERR         =0x10,
        !            63:        PAR_ERR         =0x20,
        !            64:        FRM_ERR         =0x40,
        !            65:        RCVD_BRK        =0x80,
        !            66:        BD38400         =0xCC|0x0000,
        !            67:        BD19200         =0xCC|0x0100,
        !            68:        BD9600          =0xBB|0x0000,
        !            69:        BD4800          =0x99|0x0000,
        !            70:        BD2400          =0x88|0x0000,
        !            71:        BD1200          =0x66|0x0000,
        !            72:        BD300           =0x44|0x0000,
        !            73:        IM_IPC          =0x80,  /* IMRx/ISRx - Interrupt Mask/Interrupt Status */
        !            74:        IM_DBB          =0x40,
        !            75:        IM_RRDYB        =0x20,
        !            76:        IM_XRDYB        =0x10,
        !            77:        IM_CRDY         =0x08,
        !            78:        IM_DBA          =0x04,
        !            79:        IM_RRDYA        =0x02,
        !            80:        IM_XRDYA        =0x01,
        !            81: };
        !            82: 
        !            83: /*
        !            84:  *  software info for a serial duart interface
        !            85:  */
        !            86: typedef struct Duartport       Duartport;
        !            87: struct Duartport
        !            88: {
        !            89:        QLock;
        !            90:        int     printing;       /* true if printing */
        !            91: 
        !            92:        /* console interface */
        !            93:        int     nostream;       /* can't use the stream interface */
        !            94:        IOQ     *iq;            /* input character queue */
        !            95:        IOQ     *oq;            /* output character queue */
        !            96: 
        !            97:        /* stream interface */
        !            98:        Queue   *wq;            /* write queue */
        !            99:        Rendez  r;              /* kproc waiting for input */
        !           100:        int     kstarted;       /* kproc started */
        !           101: };
        !           102: Duartport      duartport[1];
        !           103: 
        !           104: uchar keymap[]={
        !           105: /*80*/ 0x58,   0x58,   0x58,   0x58,   0x58,   0x58,   0x58,   0x58,
        !           106:        0x58,   0x58,   0x58,   0x58,   0x58,   0x58,   0x8e,   0x58,
        !           107: /*90*/ 0x90,   0x91,   0x92,   0x93,   0x94,   0x95,   0x96,   0x97,
        !           108:        0x98,   0x99,   0x9a,   0x9b,   0x58,   0x58,   0x58,   0x58,
        !           109: /*A0*/ 0x58,   0xa1,   0xa2,   0xa3,   0xa4,   0xa5,   0xa6,   0xa7,
        !           110:        0x58,   0x58,   0x58,   0x58,   0x58,   0x58,   0xae,   0xaf,
        !           111: /*B0*/ 0xb0,   0xb1,   0xb2,   0xb3,   0xb4,   0xb5,   0xb6,   0xb7,
        !           112:        0xb8,   0xb9,   0x00,   0xbb,   0x1e,   0xbd,   0x60,   0x1f,
        !           113: /*C0*/ 0xc0,   0xc1,   0xc2,   0xc3,   0xc4,   0x58,   0xc6,   0x0a,
        !           114:        0xc8,   0xc9,   0xca,   0xcb,   0xcc,   0xcd,   0xce,   0xcf,
        !           115: /*D0*/ 0x09,   0x08,   0xd2,   0xd3,   0xd4,   0xd5,   0xd6,   0xd7,
        !           116:        0x58,   0x58,   0x58,   0x58,   0x58,   0x58,   0x7f,   0x58,
        !           117: /*E0*/ 0x58,   0x58,   0xe2,   0x1b,   0x0d,   0xe5,   0x58,   0x0a,
        !           118:        0xe8,   0xe9,   0xea,   0xeb,   0xec,   0xed,   0xee,   0xef,
        !           119: /*F0*/ 0x09,   0x08,   0xb2,   0x1b,   0x0d,   0xf5,   0x81,   0x58,
        !           120:        0x58,   0x58,   0x58,   0x58,   0x58,   0x58,   0x7f,   0x80,
        !           121: };
        !           122: 
        !           123: void
        !           124: duartinit(void)
        !           125: {
        !           126:        Duart *duart;
        !           127:        static int already;
        !           128: 
        !           129:        if(already)
        !           130:                return;
        !           131:        already = 1;
        !           132: 
        !           133:        duart  =  DUARTREG;
        !           134: 
        !           135:        /*
        !           136:         * Keyboard
        !           137:         */
        !           138:        duart[0].cmnd = RESET_RCV|DIS_TX|DIS_RX;
        !           139:        duart[0].cmnd = RESET_TRANS;
        !           140:        duart[0].cmnd = RESET_ERR;
        !           141:        duart[0].cmnd = RESET_MR;
        !           142:        duart[0].mr1_2 = CHAR_ERR|PAR_ENB|EVEN_PAR|CBITS8;
        !           143:        duart[0].mr1_2 = NORM_OP|ONESTOPB;
        !           144:        duart[0].sr_csr = BD4800;
        !           145: 
        !           146:        /*
        !           147:         * RS232
        !           148:         */
        !           149:        duart[1].cmnd = RESET_RCV|DIS_TX|DIS_RX;
        !           150:        duart[1].cmnd = RESET_TRANS;
        !           151:        duart[1].cmnd = RESET_ERR;
        !           152:        duart[1].cmnd = RESET_MR;
        !           153:        duart[1].mr1_2 = CHAR_ERR|NO_PAR|CBITS8;
        !           154:        duart[1].mr1_2 = NORM_OP|ONESTOPB;
        !           155:        duart[1].sr_csr = BD9600;
        !           156: 
        !           157:        /*
        !           158:         * Output port
        !           159:         */
        !           160:        duart[0].ipc_acr = duartacr = 0xB7;     /* allow change of state interrupt */
        !           161:        duart[1].ip_opcr = 0x00;
        !           162:        duart[1].scc_ropbc = 0xFF;      /* make sure the port is reset first */
        !           163:        duart[1].scc_sopbc = 0x04;      /* dtr = 1, pp = 01 */
        !           164:        duart[0].is_imr = duartimr = IM_IPC|IM_RRDYB|IM_XRDYB|IM_RRDYA|IM_XRDYA;
        !           165:        duart[0].cmnd = ENB_TX|ENB_RX;  /* enable TX and RX last */
        !           166:        duart[1].cmnd = ENB_TX|ENB_RX;
        !           167: 
        !           168:        /*
        !           169:         * Initialize keyboard
        !           170:         */
        !           171:        while (!(duart[0].sr_csr & (XMT_EMT|XMT_RDY)))
        !           172:                ;
        !           173:        duart[0].data = 0x02;
        !           174: }
        !           175: 
        !           176: 
        !           177: void
        !           178: duartbaud(int b)
        !           179: {
        !           180:        int x = 0;
        !           181:        Duart *duart = DUARTREG;
        !           182: 
        !           183:        switch(b){
        !           184:        case 38400:
        !           185:                x = BD38400;
        !           186:                break;
        !           187:        case 19200:
        !           188:                x = BD19200;
        !           189:                break;
        !           190:        case 9600:
        !           191:                x = BD9600;
        !           192:                break;
        !           193:        case 4800:
        !           194:                x = BD4800;
        !           195:                break;
        !           196:        case 2400:
        !           197:                x = BD2400;
        !           198:                break;
        !           199:        case 1200:
        !           200:                x = BD1200;
        !           201:                break;
        !           202:        case 300:
        !           203:                x = BD300;
        !           204:                break;
        !           205:        default:
        !           206:                error(Ebadarg);
        !           207:        }
        !           208:        if(x & 0x0100)
        !           209:                duart[0].ipc_acr = duartacr |= 0x80;
        !           210:        else
        !           211:                duart[0].ipc_acr = duartacr &= ~0x80;
        !           212:        duart[1].sr_csr = x;
        !           213: }
        !           214: 
        !           215: void
        !           216: duartdtr(int val)
        !           217: {
        !           218:        Duart *duart = DUARTREG;
        !           219:        if (val)
        !           220:                duart[1].scc_ropbc=0x01;
        !           221:        else
        !           222:                duart[1].scc_sopbc=0x01;
        !           223: }
        !           224: 
        !           225: void
        !           226: duartbreak(int ms)
        !           227: {
        !           228:        static QLock brk;
        !           229:        Duart *duart = DUARTREG;
        !           230:        if (ms<=0 || ms >20000)
        !           231:                error(Ebadarg);
        !           232:        qlock(&brk);
        !           233:        duart[0].is_imr = duartimr &= ~IM_XRDYB;
        !           234:        duart[1].cmnd = STRT_BRK|ENB_TX;
        !           235:        tsleep(&u->p->sleep, return0, 0, ms);
        !           236:        duart[1].cmnd = STOP_BRK|ENB_TX;
        !           237:        duart[0].is_imr = duartimr |= IM_XRDYB;
        !           238:        qunlock(&brk);
        !           239: }
        !           240: 
        !           241: enum{
        !           242:        Kptime=200
        !           243: };
        !           244: void
        !           245: duartstarttimer(void)
        !           246: {
        !           247:        Duart *duart;
        !           248:        char x;
        !           249: 
        !           250:        duart = DUARTREG;
        !           251:        duart[0].ctur = (Kptime)>>8;
        !           252:        duart[0].ctlr = (Kptime)&255;
        !           253:        duart[0].is_imr = duartimr |= IM_CRDY;
        !           254:        x = duart[1].scc_sopbc;
        !           255:        USED(x);
        !           256: }
        !           257: 
        !           258: void
        !           259: duartstoptimer(void)
        !           260: {
        !           261:        Duart *duart;
        !           262:        char x;
        !           263: 
        !           264:        duart = DUARTREG;
        !           265:        x = duart[1].scc_ropbc;
        !           266:        USED(x);
        !           267:        duart[0].is_imr = duartimr &= ~IM_CRDY;
        !           268: }
        !           269: 
        !           270: 
        !           271: /*
        !           272:  *  a serial line input interrupt
        !           273:  */
        !           274: void
        !           275: duartrintr(char ch)
        !           276: {
        !           277:        IOQ *cq;
        !           278:        Duartport *dp = duartport;
        !           279: 
        !           280:        cq = dp->iq;
        !           281:        if(cq->putc)
        !           282:                (*cq->putc)(cq, ch);
        !           283:        else {
        !           284:                putc(cq, ch);
        !           285:        }
        !           286: }
        !           287: void
        !           288: duartclock(void)
        !           289: {
        !           290:        Duartport *dp = duartport;
        !           291:        IOQ *cq;
        !           292: 
        !           293:        cq = dp->iq;
        !           294:        if(cangetc(cq))
        !           295:                wakeup(&cq->r);
        !           296: }
        !           297: 
        !           298: /*
        !           299:  *  a serial line output interrupt
        !           300:  */
        !           301: void
        !           302: duartxintr(void)
        !           303: {
        !           304:        int ch;
        !           305:        IOQ *cq;
        !           306:        Duartport *dp = duartport;
        !           307:        Duart *duart;
        !           308: 
        !           309:        cq = dp->oq;
        !           310:        lock(cq);
        !           311:        ch = getc(cq);
        !           312:        duart = DUARTREG;
        !           313:        if(ch < 0){
        !           314:                dp->printing = 0;
        !           315:                wakeup(&cq->r);
        !           316:                duart[1].cmnd = DIS_TX;
        !           317:        } else
        !           318:                duart[1].data = ch;
        !           319:        unlock(cq);
        !           320: }
        !           321: 
        !           322: 
        !           323: void
        !           324: duartintr(Ureg *ur)
        !           325: {
        !           326:        int cause, status, ch, c, i;
        !           327:        Duart *duart;
        !           328:        static int collecting, nk;
        !           329:        static uchar kc[5];
        !           330: 
        !           331:        duart = DUARTREG;
        !           332:        cause = duart->is_imr;
        !           333:        /*
        !           334:         * I can guess your interrupt.
        !           335:         */
        !           336:        /*
        !           337:         * Is it 0?
        !           338:         */
        !           339:        if(cause & IM_CRDY){
        !           340:                if(kprofp)
        !           341:                        (*kprofp)(ur->pc);
        !           342:                ch = duart[1].scc_ropbc;
        !           343:                USED(ch);
        !           344:                duart[0].ctur = (Kptime)>>8;
        !           345:                duart[0].ctlr = (Kptime)&255;
        !           346:                ch = duart[1].scc_sopbc;
        !           347:                USED(ch);
        !           348:                return;
        !           349:        }
        !           350:        /*
        !           351:         * Is it 1?
        !           352:         */
        !           353:        if(cause & IM_RRDYA){           /* keyboard input */
        !           354:                status = duart->sr_csr;
        !           355:                ch = duart->data;
        !           356:                if(status & (FRM_ERR|OVR_ERR|PAR_ERR))
        !           357:                        duart->cmnd = RESET_ERR;
        !           358:                if(status & PAR_ERR) /* control word: caps lock (0x4) or repeat (0x10) */
        !           359:                        kbdrepeat((ch&0x10) == 0);
        !           360:                else{
        !           361:                        if(ch == 0x7F)  /* VIEW key (bizarre) */
        !           362:                                ch = 0xFF;
        !           363:                        if(ch == 0xB6)  /* NUM PAD */
        !           364:                                collecting = 1;
        !           365:                        else{
        !           366:                                if(ch & 0x80)
        !           367:                                        ch = keymap[ch&0x7F];
        !           368:                                if(!collecting)
        !           369:                                        kbdputc(&kbdq, ch);
        !           370:                                else{
        !           371:                                        kc[nk++] = ch;
        !           372:                                        c = latin1(kc, nk);
        !           373:                                        if(c >= -1){    /* otherwise need more keystrokes */
        !           374:                                                if(c != -1)     /* valid sequence */
        !           375:                                                        kbdputc(&kbdq, c);
        !           376:                                                else    /* dump characters */
        !           377:                                                        for(i=0; i<nk; i++)
        !           378:                                                                kbdputc(&kbdq, kc[i]);
        !           379:                                                nk = 0;
        !           380:                                                collecting = 0;
        !           381:                                        }
        !           382:                                }
        !           383:                        }
        !           384:                }
        !           385:        }
        !           386:        /*
        !           387:         * Is it 2?
        !           388:         */
        !           389:        while(cause & IM_RRDYB){        /* duart input */
        !           390:                status = duart[1].sr_csr;
        !           391:                ch = duart[1].data;
        !           392:                if(status & (FRM_ERR|OVR_ERR|PAR_ERR))
        !           393:                        duart[1].cmnd = RESET_ERR;
        !           394:                else
        !           395:                        duartrintr(ch);
        !           396:                cause = duart->is_imr;
        !           397:        }
        !           398:        /*
        !           399:         * Is it 3?
        !           400:         */
        !           401:        if(cause & IM_XRDYB)            /* duart output */
        !           402:                duartxintr();
        !           403:        /*
        !           404:         * Is it 4?
        !           405:         */
        !           406:        if(cause & IM_XRDYA)
        !           407:                duart[0].cmnd = DIS_TX;
        !           408:        /*
        !           409:         * Is it 5?
        !           410:         */
        !           411:        if(cause & IM_IPC)
        !           412:                mousetrack((~duart[0].ipc_acr) & 7, 0, 0);
        !           413: }
        !           414: 
        !           415: 
        !           416: /*
        !           417:  *  Queue n characters for output; if queue is full, we lose characters.
        !           418:  *  Get the output going if it isn't already.
        !           419:  */
        !           420: void
        !           421: duartputs(IOQ *cq, char *s, int n)
        !           422: {
        !           423:        int ch, x;
        !           424:        Duartport *dp = duartport;
        !           425:        Duart *duart;
        !           426: 
        !           427:        x = splduart();
        !           428:        lock(cq);
        !           429:        puts(cq, s, n);
        !           430:        if(dp->printing == 0){
        !           431:                ch = getc(cq);
        !           432:                if(ch >= 0){
        !           433:                        dp->printing = 1;
        !           434:                        duart = DUARTREG;
        !           435:                        duart[1].cmnd = ENB_TX;
        !           436:                        while(!(duart[1].sr_csr & (XMT_RDY|XMT_EMT)))
        !           437:                                ;
        !           438:                        duart[1].data = ch;
        !           439:                }
        !           440:        }
        !           441:        unlock(cq);
        !           442:        splx(x);
        !           443: }
        !           444: 
        !           445: void
        !           446: duartenable(Duartport *dp)
        !           447: {
        !           448:        /*
        !           449:         *  set up i/o routines
        !           450:         */
        !           451:        if(dp->oq){
        !           452:                dp->oq->puts = duartputs;
        !           453:                dp->oq->ptr = dp;
        !           454:        }
        !           455:        if(dp->iq)
        !           456:                dp->iq->ptr = dp;
        !           457: }
        !           458: 
        !           459: /*
        !           460:  *  set up an duart port as something other than a stream
        !           461:  */
        !           462: void
        !           463: duartspecial(int port, IOQ *oq, IOQ *iq, int baud)
        !           464: {
        !           465:        Duartport *dp = &duartport[port];
        !           466: 
        !           467:        dp->nostream = 1;
        !           468:        dp->oq = oq;
        !           469:        dp->iq = iq;
        !           470:        duartenable(dp);
        !           471:        duartbaud(baud);
        !           472: }
        !           473: 
        !           474: static int     duartputc(IOQ *, int);
        !           475: static void    duartstopen(Queue*, Stream*);
        !           476: static void    duartstclose(Queue*);
        !           477: static void    duartoput(Queue*, Block*);
        !           478: static void    duartkproc(void *);
        !           479: Qinfo duartinfo =
        !           480: {
        !           481:        nullput,
        !           482:        duartoput,
        !           483:        duartstopen,
        !           484:        duartstclose,
        !           485:        "duart"
        !           486: };
        !           487: 
        !           488: static void
        !           489: duartstopen(Queue *q, Stream *s)
        !           490: {
        !           491:        Duartport *dp;
        !           492:        char name[NAMELEN];
        !           493: 
        !           494:        if(s->id > 0)
        !           495:                panic("duartstopen");
        !           496:        dp = &duartport[s->id];
        !           497: 
        !           498:        qlock(dp);
        !           499:        dp->wq = WR(q);
        !           500:        WR(q)->ptr = dp;
        !           501:        RD(q)->ptr = dp;
        !           502:        qunlock(dp);
        !           503: 
        !           504:        if(dp->kstarted == 0){
        !           505:                dp->kstarted = 1;
        !           506:                sprint(name, "duart%d", s->id);
        !           507:                kproc(name, duartkproc, dp);
        !           508:        }
        !           509: }
        !           510: 
        !           511: static void
        !           512: duartstclose(Queue *q)
        !           513: {
        !           514:        Duartport *dp = q->ptr;
        !           515: 
        !           516:        qlock(dp);
        !           517:        dp->wq = 0;
        !           518:        dp->iq->putc = 0;
        !           519:        WR(q)->ptr = 0;
        !           520:        RD(q)->ptr = 0;
        !           521:        qunlock(dp);
        !           522: }
        !           523: 
        !           524: static void
        !           525: duartoput(Queue *q, Block *bp)
        !           526: {
        !           527:        Duartport *dp = q->ptr;
        !           528:        IOQ *cq;
        !           529:        int n, m;
        !           530: 
        !           531:        if(dp == 0){
        !           532:                freeb(bp);
        !           533:                return;
        !           534:        }
        !           535:        cq = dp->oq;
        !           536:        if(waserror()){
        !           537:                freeb(bp);
        !           538:                nexterror();
        !           539:        }
        !           540:        if(bp->type == M_CTL){
        !           541:                while (cangetc(cq))     /* let output drain */
        !           542:                        sleep(&cq->r, cangetc, cq);
        !           543:                n = strtoul((char *)(bp->rptr+1), 0, 0);
        !           544:                switch(*bp->rptr){
        !           545:                case 'B':
        !           546:                case 'b':
        !           547:                        duartbaud(n);
        !           548:                        break;
        !           549:                case 'D':
        !           550:                case 'd':
        !           551:                        duartdtr(n);
        !           552:                        break;
        !           553:                case 'K':
        !           554:                case 'k':
        !           555:                        duartbreak(n);
        !           556:                        break;
        !           557:                case 'R':
        !           558:                case 'r':
        !           559:                        /* can't control? */
        !           560:                        break;
        !           561:                case 'W':
        !           562:                case 'w':
        !           563:                        /* obsolete */
        !           564:                        break;
        !           565:                }
        !           566:        }else while((m = BLEN(bp)) > 0){
        !           567:                while ((n = canputc(cq)) == 0){
        !           568:                        kprint(" duartoput: sleeping\n");
        !           569:                        sleep(&cq->r, canputc, cq);
        !           570:                }
        !           571:                if(n > m)
        !           572:                        n = m;
        !           573:                (*cq->puts)(cq, bp->rptr, n);
        !           574:                bp->rptr += n;
        !           575:        }
        !           576:        poperror();
        !           577:        freeb(bp);
        !           578: }
        !           579: 
        !           580: /*
        !           581:  *  process to send bytes upstream for a port
        !           582:  */
        !           583: static void
        !           584: duartkproc(void *a)
        !           585: {
        !           586:        Duartport *dp = a;
        !           587:        IOQ *cq = dp->iq;
        !           588:        Block *bp;
        !           589:        int n;
        !           590: 
        !           591: loop:
        !           592:        while ((n = cangetc(cq)) == 0)
        !           593:                sleep(&cq->r, cangetc, cq);
        !           594:        qlock(dp);
        !           595:        if(dp->wq == 0){
        !           596:                cq->out = cq->in;
        !           597:        }else{
        !           598:                bp = allocb(n);
        !           599:                bp->flags |= S_DELIM;
        !           600:                bp->wptr += gets(cq, bp->wptr, n);
        !           601:                PUTNEXT(RD(dp->wq), bp);
        !           602:        }
        !           603:        qunlock(dp);
        !           604:        goto loop;
        !           605: }
        !           606: 
        !           607: enum{
        !           608:        Qdir=           0,
        !           609:        Qeia0=          STREAMQID(0, Sdataqid),
        !           610:        Qeia0ctl=       STREAMQID(0, Sctlqid),
        !           611: };
        !           612: 
        !           613: Dirtab duartdir[]={
        !           614:        "eia0",         {Qeia0},        0,              0666,
        !           615:        "eia0ctl",      {Qeia0ctl},     0,              0666,
        !           616: };
        !           617: 
        !           618: #define        NDuartport      (sizeof duartdir/sizeof(Dirtab))
        !           619: 
        !           620: /*
        !           621:  *  allocate the queues if no one else has
        !           622:  */
        !           623: void
        !           624: duartreset(void)
        !           625: {
        !           626:        Duartport *dp = duartport;
        !           627: 
        !           628:        if(dp->nostream)
        !           629:                return;
        !           630:        dp->iq = xalloc(sizeof(IOQ));
        !           631:        initq(dp->iq);
        !           632:        dp->oq = xalloc(sizeof(IOQ));
        !           633:        initq(dp->oq);
        !           634:        duartenable(dp);
        !           635: }
        !           636: 
        !           637: Chan*
        !           638: duartattach(char *spec)
        !           639: {
        !           640:        return devattach('t', spec);
        !           641: }
        !           642: 
        !           643: Chan*
        !           644: duartclone(Chan *c, Chan *nc)
        !           645: {
        !           646:        return devclone(c, nc);
        !           647: }
        !           648: 
        !           649: int
        !           650: duartwalk(Chan *c, char *name)
        !           651: {
        !           652:        return devwalk(c, name, duartdir, NDuartport, devgen);
        !           653: }
        !           654: 
        !           655: void
        !           656: duartstat(Chan *c, char *dp)
        !           657: {
        !           658:        switch(c->qid.path){
        !           659:        case Qeia0:
        !           660:                streamstat(c, dp, duartdir[0].name, duartdir[0].perm);
        !           661:                break;
        !           662:        default:
        !           663:                devstat(c, dp, duartdir, NDuartport, devgen);
        !           664:                break;
        !           665:        }
        !           666: }
        !           667: 
        !           668: Chan*
        !           669: duartopen(Chan *c, int omode)
        !           670: {
        !           671:        Duartport *dp;
        !           672: 
        !           673:        switch(c->qid.path){
        !           674:        case Qeia0:
        !           675:        case Qeia0ctl:
        !           676:                dp = &duartport[0];
        !           677:                break;
        !           678:        default:
        !           679:                dp = 0;
        !           680:                break;
        !           681:        }
        !           682: 
        !           683:        if(dp && dp->nostream)
        !           684:                error(Einuse);
        !           685: 
        !           686:        if((c->qid.path & CHDIR) == 0)
        !           687:                streamopen(c, &duartinfo);
        !           688:        return devopen(c, omode, duartdir, NDuartport, devgen);
        !           689: }
        !           690: 
        !           691: void
        !           692: duartcreate(Chan *c, char *name, int omode, ulong perm)
        !           693: {
        !           694:        USED(c, name, omode, perm);
        !           695:        error(Eperm);
        !           696: }
        !           697: 
        !           698: void
        !           699: duartclose(Chan *c)
        !           700: {
        !           701:        if(c->stream)
        !           702:                streamclose(c);
        !           703: }
        !           704: 
        !           705: long
        !           706: duartread(Chan *c, void *buf, long n, ulong offset)
        !           707: {
        !           708:        int s;
        !           709:        Duart *duart = DUARTREG;
        !           710: 
        !           711:        switch(c->qid.path&~CHDIR){
        !           712:        case Qdir:
        !           713:                return devdirread(c, buf, n, duartdir, NDuartport, devgen);
        !           714:        case Qeia0ctl:
        !           715:                if(offset)
        !           716:                        return 0;
        !           717:                s = splhi();
        !           718:                *(uchar *)buf = duart[1].ip_opcr;
        !           719:                splx(s);
        !           720:                return 1;
        !           721:        }
        !           722:        return streamread(c, buf, n);
        !           723: }
        !           724: 
        !           725: long
        !           726: duartwrite(Chan *c, void *va, long n, ulong offset)
        !           727: {
        !           728:        USED(offset);
        !           729:        return streamwrite(c, va, n, 0);
        !           730: }
        !           731: 
        !           732: void
        !           733: duartremove(Chan *c)
        !           734: {
        !           735:        USED(c);
        !           736:        error(Eperm);
        !           737: }
        !           738: 
        !           739: void
        !           740: duartwstat(Chan *c, char *dp)
        !           741: {
        !           742:        USED(c, dp);
        !           743:        error(Eperm);
        !           744: }

unix.superglobalmegacorp.com

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