Annotation of cci/sys/tahoe/cons.c, revision 1.1

1.1     ! root        1: /*     cons.c  4.10    81/05/09        */
        !             2: /*     Tahoe version Dec 1982          */
        !             3: /*     Minor device 0 is the CP itself.
        !             4: /*       No real read/writes can be done to him.
        !             5: /*     Minor 1 is the console terminal.
        !             6: /*     Minor 2 is the remote line trminal.
        !             7: /**/
        !             8: 
        !             9: /*
        !            10:  * Tahoe console processor driver
        !            11:  *
        !            12:  */
        !            13: #include "../h/param.h"
        !            14: #include "../h/conf.h"
        !            15: #include "../h/dir.h"
        !            16: #include "../h/ioctl.h"
        !            17: #include "../h/user.h"
        !            18: #include "../h/tty.h"
        !            19: #include "../h/uio.h"
        !            20: #include "../h/callout.h"
        !            21: #include "../h/systm.h"
        !            22: #include "../machine/cp.h"
        !            23: #include "../machine/mtpr.h"
        !            24: 
        !            25: #define FALSE 0
        !            26: #define TRUE  1
        !            27: 
        !            28: int    cnrestart() ;
        !            29: int    timeout() ;
        !            30: 
        !            31: struct tty cons[3];    /* One for each unit on CP */
        !            32: struct cons_info {
        !            33:        char    last_one;       /* Last char sent - possibly repeat
        !            34:                                 * If zero, timeout has nothing to do
        !            35:                                 */
        !            36:        int     active_timeout; /* There is an active timeout for this line
        !            37:                                 * Set by 'cnputc' when a timeout is initiated.
        !            38:                                 * Reset by the routine  called at timeout.
        !            39:                                 */
        !            40:        int     try_later;      /* If true, timeout has nothing to do.
        !            41:                                 * Set by 'cnputc' every time a char is sent.
        !            42:                                 * Reset by the timeout arrival. If next time
        !            43:                                 * the timeout comes it's zero, then it may
        !            44:                                 * have something to do.
        !            45:                                 */
        !            46:        } cons_info[3];
        !            47: struct cpdcb_o consout[3] = { 
        !            48:                        /*      unit,           cmd,count, buf */
        !            49:                        {(char)(CPTAKE | CPDONE),0,   0 },
        !            50:                        {(char)(CPTAKE | CPDONE),0,   0 },
        !            51:                        {(char)(CPTAKE | CPDONE),0,   0 }
        !            52:                        };
        !            53: struct cpdcb_i consin[3] = {
        !            54:                        /*      unit,           cmd,count, buf */
        !            55:                        {(char)(CPTAKE | CPDONE),0,   0 },
        !            56:                        {(char)(CPTAKE | CPDONE),0,   0 },
        !            57:                        {(char)(CPTAKE | CPDONE),0,   0 }
        !            58:                        };
        !            59: struct cphdr *lasthdr;
        !            60: 
        !            61: int    cnstart();
        !            62: int    ttrstrt();
        !            63: char   partab[];
        !            64: 
        !            65: cnopen(dev, flag)
        !            66: dev_t dev;
        !            67: {
        !            68:        register struct cpdcb_i *cin;
        !            69:        register struct tty *tp;
        !            70:        register int timo;
        !            71: 
        !            72:        if (minor(dev) > CPREMOT) 
        !            73:                return EEXIST;
        !            74:        tp = &cons[minor(dev)];
        !            75:        if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
        !            76:                return EBUSY;
        !            77:        if (lasthdr != (struct cphdr *)0) {
        !            78:                timo = 10000;
        !            79:                uncache((char *)&lasthdr->cp_unit);
        !            80:                while ((lasthdr->cp_unit & CPTAKE)==0 && --timo )
        !            81:                        uncache((char *)&lasthdr->cp_unit);
        !            82:        }       /* Here we give up waiting */
        !            83:        cin = &consin[minor(dev)];
        !            84:        cin->cp_hdr.cp_unit = (char)(minor(dev));
        !            85:        cin->cp_hdr.cp_comm = (char)CPREAD;
        !            86:        cin->cp_hdr.cp_count = 1;       /* Get ready for input */
        !            87:        mtpr (cin, CPMDCB);
        !            88:        lasthdr = (struct cphdr *)cin;
        !            89:        tp->t_oproc = cnstart;
        !            90:        tp->t_dev = dev;
        !            91:        if ((tp->t_state&TS_ISOPEN) == 0) {
        !            92:                ttychars(tp);
        !            93:                tp->t_state = TS_ISOPEN|TS_CARR_ON;
        !            94:                tp->t_flags = EVENP|ECHO|XTABS|CRMOD;
        !            95:        }
        !            96:        (*linesw[tp->t_line].l_open)(dev, tp);
        !            97: }
        !            98: 
        !            99: cnclose(dev)
        !           100: dev_t dev;
        !           101: {
        !           102:        register struct tty *tp = &cons[minor(dev)];
        !           103: 
        !           104:        (*linesw[tp->t_line].l_close)(tp);
        !           105:        ttyclose(tp);
        !           106: }
        !           107: 
        !           108: /*ARGSUSED*/
        !           109: cnread(dev, uio)
        !           110:        dev_t dev;
        !           111:        struct uio *uio;
        !           112: {
        !           113:        register struct tty *tp = &cons[minor(dev)];
        !           114: 
        !           115:        return ((*linesw[tp->t_line].l_read)(tp, uio));
        !           116: }
        !           117: 
        !           118: /*ARGSUSED*/
        !           119: cnwrite(dev, uio)
        !           120:        dev_t dev;
        !           121:        struct uio *uio;
        !           122: {
        !           123:        register struct tty *tp = &cons[minor(dev)];
        !           124: 
        !           125:        return ((*linesw[tp->t_line].l_write)(tp, uio));
        !           126: }
        !           127: 
        !           128: /*
        !           129:  * Got a console receive interrupt -
        !           130:  * the console processor wants to give us a character.
        !           131:  * Catch the character, and see who it goes to.
        !           132:  */
        !           133: cnrint(dev)
        !           134: dev_t dev;
        !           135: {
        !           136:        register int c, timo;
        !           137:        register struct tty *tp;
        !           138: 
        !           139:        if (intenable == 0) return;
        !           140:        /* make sure we dont take it from cache */
        !           141:        uncache((char *)&consin[minor(dev)].cpi_buf[0]);
        !           142:        c = consin[minor(dev)].cpi_buf[0];
        !           143: /*
        !           144: /* Wait about 5 milli for last CPMDCB to be read by CP,
        !           145: /* otherwise give up
        !           146: /**/
        !           147:        timo = 10000;
        !           148:        uncache((char *)&lasthdr->cp_unit);
        !           149:        while ((lasthdr->cp_unit & CPTAKE)==0  && --timo  )
        !           150:                uncache((char *)&lasthdr->cp_unit);
        !           151:        uncache((char *)&lasthdr->cp_unit);
        !           152:        if (lasthdr->cp_unit & CPTAKE)
        !           153:        {
        !           154:                consin[minor(dev)].cp_hdr.cp_unit = (char)(minor(dev));
        !           155:                        /* This resets status bits */
        !           156:                mtpr (&consin[minor(dev)], CPMDCB); /* Ready for new character */
        !           157:                lasthdr = (struct cphdr *)&consin[minor(dev)];
        !           158:                tp = &cons[minor(dev)];
        !           159:                (*linesw[tp->t_line].l_rint)(c, tp);
        !           160:        }
        !           161: }
        !           162: 
        !           163: cnioctl(dev, cmd, addr, flag)
        !           164: dev_t dev;
        !           165: caddr_t addr;
        !           166: {
        !           167:        register struct tty *tp = &cons[minor(dev)];
        !           168:        register error;
        !           169:  
        !           170:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
        !           171:        if (error >= 0)
        !           172:                return error;
        !           173:        if ((error = ttioctl(tp, cmd, addr, flag)) < 0)
        !           174:                error = ENOTTY;
        !           175:        else if(cmd==TIOCSETP || cmd==TIOCSETN)
        !           176:                cnparams(tp);
        !           177:        return error;
        !           178: }
        !           179: 
        !           180: int    consintr = 1;
        !           181: /*
        !           182:  * Got a console transmission interrupt -
        !           183:  * the console processor wants another character.
        !           184:  */
        !           185: cnxint(dev)
        !           186: dev_t dev;
        !           187: {
        !           188:        register struct tty *tp;
        !           189:        register int line_no;
        !           190: 
        !           191:        if (intenable == 0 || consintr == 0) return;
        !           192: #ifdef CPPERF
        !           193:        if (minor(dev)==CPCONS) scope_in(1);
        !           194:        else scope_in(2);
        !           195: #endif
        !           196:        line_no = minor(dev);
        !           197:        tp = &cons[line_no];
        !           198:        tp->t_state &= ~TS_BUSY;
        !           199:        cons_info[line_no].last_one = (char)0;
        !           200:        if (tp->t_line)
        !           201:                (*linesw[tp->t_line].l_start)(tp);
        !           202:        else
        !           203:                cnstart(tp);
        !           204: }
        !           205: 
        !           206: cnstart(tp)
        !           207: register struct tty *tp;
        !           208: {
        !           209:        register c;
        !           210:        register s;
        !           211: 
        !           212: #ifdef CPPERF
        !           213:        if (minor(tp->t_dev)==CPCONS) scope_in(3);
        !           214:        else scope_in(4);
        !           215: #endif
        !           216:        s = spl8();
        !           217:        if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
        !           218:                goto out;
        !           219:        if (tp->t_outq.c_cc <= TTLOWAT(tp)) {
        !           220:                if (tp->t_state&TS_ASLEEP) {
        !           221:                        tp->t_state &= ~TS_ASLEEP;
        !           222:                        wakeup((caddr_t)&tp->t_outq);
        !           223:                }
        !           224:                if (tp->t_wsel) {
        !           225:                        selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
        !           226:                        tp->t_wsel = 0;
        !           227:                        tp->t_state &= ~TS_WCOLL;
        !           228:                }
        !           229:        }
        !           230:        if (tp->t_outq.c_cc == 0)
        !           231:                goto out;
        !           232:        c = getc(&tp->t_outq) & 0xff;
        !           233:        if (tp->t_flags&(RAW|LITOUT))
        !           234:                cnputc(c,tp);
        !           235:        else if (c<=0177)
        !           236:                cnputc ((c | (partab[c]&0200))&0xff,tp);
        !           237:        else {
        !           238:                timeout(ttrstrt, (caddr_t)tp, (c&0177));
        !           239:                tp->t_state |= TS_TIMEOUT;
        !           240:                goto out;
        !           241:        }
        !           242:        tp->t_state |= TS_BUSY;
        !           243:     out:
        !           244:        splx(s);
        !           245: }
        !           246: 
        !           247: /*
        !           248:  * Print a character on console.
        !           249:  */
        !           250: cnputc(c,tp)
        !           251: register char c;
        !           252: register struct tty *tp;
        !           253: {
        !           254:        register timo , line_no, s;
        !           255:        register struct cpdcb_o *current;
        !           256: 
        !           257:        /* tp == 0 only in system error messages */
        !           258:        if (tp == 0) {
        !           259:                current = &consout[CPCONS];
        !           260:                line_no = CPCONS;
        !           261:                if(lasthdr == 0)        /* not done anythig yet */
        !           262:                        lasthdr = (struct cphdr *)current;
        !           263:                c |= partab[c&0177]&0200;
        !           264:        }
        !           265:        else {
        !           266:                current = &consout[minor(tp->t_dev)];
        !           267:                line_no = minor(tp->t_dev);
        !           268:        }
        !           269:        timo = 30000;
        !           270:        /*
        !           271:         * Try waiting for the console tty to come ready,
        !           272:         * otherwise give up after a reasonable time.
        !           273:         * make sure we dont test this bit in cache!
        !           274:         */
        !           275:        uncache((char *)&current->cp_hdr.cp_unit);
        !           276:        while ((current->cp_hdr.cp_unit & CPDONE) == 0 && --timo )
        !           277:                uncache((char *)&current->cp_hdr.cp_unit);
        !           278:        current->cp_hdr.cp_comm = (char)CPWRITE;
        !           279:        current->cp_hdr.cp_count = 1;
        !           280:        current->cp_buf[0] = (char)(c & 0xff);
        !           281:        timo = 10000;
        !           282:        /*
        !           283:         * Try waiting for the console tty to come ready,
        !           284:         * otherwise give up after a reasonable time.
        !           285:         */
        !           286:        uncache((char *)&lasthdr->cp_unit);
        !           287:        while ((lasthdr->cp_unit & CPTAKE)==0 && --timo )
        !           288:                uncache((char *)&lasthdr->cp_unit);
        !           289:        /* Reset done bit */
        !           290:        current->cp_hdr.cp_unit = (char)line_no; 
        !           291:        lasthdr = (struct cphdr *)current;
        !           292: #ifdef CPPERF
        !           293:        if (intenable != 0) scope_in(5);
        !           294: #endif
        !           295:        cons_info[line_no].last_one = c;
        !           296:        if ( !cons_info[line_no].active_timeout && clk_enable) {
        !           297:                cons_info[line_no].active_timeout = TRUE;
        !           298:                timeout (cnrestart, (caddr_t)tp, 10);
        !           299:        }
        !           300:        cons_info[line_no].try_later = TRUE; /* For timeout-means wait some more */
        !           301:        mtpr (current, CPMDCB);
        !           302: }
        !           303: 
        !           304: /*
        !           305:  * Restart (if necessary) transfer to CP line.
        !           306:  * This way, lost 'transmit' interrupts don't break the chain.
        !           307:  */
        !           308: cnrestart (tp)
        !           309: struct tty *tp;
        !           310: {
        !           311:        register line_no, s;
        !           312: 
        !           313:        if (tp == 0) {
        !           314:                line_no = CPCONS;
        !           315:        } else
        !           316:                line_no = minor(tp->t_dev);
        !           317:        if (cons_info[line_no].try_later) {
        !           318:                cons_info[line_no].try_later = FALSE;
        !           319:                timeout (cnrestart, (caddr_t)tp, 10);
        !           320:        }
        !           321:        else {
        !           322:                cons_info[line_no].active_timeout = FALSE;
        !           323:                if (cons_info[line_no].last_one != (char)0)
        !           324:                        cnputc (cons_info[line_no].last_one, tp);
        !           325:        }
        !           326: }
        !           327: 
        !           328: /*
        !           329:  * Set line parameters
        !           330:  */
        !           331: cnparams(tp)
        !           332: register struct tty *tp;
        !           333: {
        !           334:        register timo ;
        !           335:        register struct cpdcb_o *current;
        !           336:        register struct cpdcb_i *cin;
        !           337: 
        !           338:        current = &consout[minor(tp->t_dev)];
        !           339:        timo = 30000;
        !           340:        /*
        !           341:         * Try waiting for the console tty to come ready,
        !           342:         * otherwise give up after a reasonable time.
        !           343:         * make sure we dont test this bit in cache!
        !           344:         */
        !           345:        uncache((char *)&current->cp_hdr.cp_unit);
        !           346:        while ((current->cp_hdr.cp_unit & CPDONE) == 0 && --timo )
        !           347:                uncache((char *)&current->cp_hdr.cp_unit);
        !           348:        current->cp_hdr.cp_comm = (char)CPSTTY;
        !           349:        current->cp_hdr.cp_count = 4;
        !           350:        current->cp_buf[0] = tp->t_ispeed;
        !           351:        /* the rest are defaults */
        !           352:        current->cp_buf[1] = 0; /* no parity */
        !           353:        current->cp_buf[2] = 0; /* stop bits */
        !           354:        current->cp_buf[3] = 8; /* data bits */
        !           355:        timo = 10000;
        !           356:        /*
        !           357:         * Try waiting for the console tty to come ready,
        !           358:         * otherwise give up after a reasonable time.
        !           359:         */
        !           360:        uncache((char *)&lasthdr->cp_unit);
        !           361:        while ((lasthdr->cp_unit & CPTAKE)==0 && --timo )
        !           362:                uncache((char *)&lasthdr->cp_unit);
        !           363:        /* Reset done bit */
        !           364:        current->cp_hdr.cp_unit = (char)minor(tp->t_dev); 
        !           365:        lasthdr = (struct cphdr *)current;
        !           366:        mtpr (current, CPMDCB);
        !           367: 
        !           368:        timo = 10000;
        !           369:        uncache((char *)&lasthdr->cp_unit);
        !           370:        while ((lasthdr->cp_unit & CPTAKE)==0 && --timo )
        !           371:                uncache((char *)&lasthdr->cp_unit);
        !           372:        cin = &consin[minor(tp->t_dev)];
        !           373:        cin->cp_hdr.cp_unit = (char)(minor(tp->t_dev));
        !           374:        cin->cp_hdr.cp_comm = (char)CPREAD;
        !           375:        cin->cp_hdr.cp_count = 1;       /* Get ready for input */
        !           376:        mtpr (cin, CPMDCB);
        !           377:        lasthdr = (struct cphdr *)cin;
        !           378: 
        !           379: }

unix.superglobalmegacorp.com

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