Annotation of lucent/sys/src/9/gnot/devduart.c, revision 1.1.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.