Annotation of cci/sys/tahoe/cons.c, revision 1.1.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.