Annotation of 41BSD/4.0.upgrade/sys/dev/dz.c, revision 1.1.1.1

1.1       root        1: /*     dz.c    4.29    81/08/31        */
                      2: 
                      3: #include "dz.h"
                      4: #if NDZ > 0
                      5: /*
                      6:  *  DZ-11 Driver
                      7:  *
                      8:  * This driver mimics dh.c; see it for explanation of common code.
                      9:  */
                     10: #include "bk.h"
                     11: #include "../h/param.h"
                     12: #include "../h/systm.h"
                     13: #include "../h/tty.h"
                     14: #include "../h/dir.h"
                     15: #include "../h/user.h"
                     16: #include "../h/map.h"
                     17: #include "../h/pte.h"
                     18: #include "../h/buf.h"
                     19: #include "../h/vm.h"
                     20: #include "../h/ubavar.h"
                     21: #include "../h/conf.h"
                     22: #include "../h/pdma.h"
                     23: #include "../h/bk.h"
                     24: #include "../h/file.h"
                     25: #include "../h/mx.h"
                     26: 
                     27: /*
                     28:  * Driver information for auto-configuration stuff.
                     29:  */
                     30: int    dzprobe(), dzattach(), dzrint();
                     31: struct uba_device *dzinfo[NDZ];
                     32: u_short        dzstd[] = { 0 };
                     33: struct uba_driver dzdriver =
                     34:        { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo };
                     35: 
                     36: #define        NDZLINE         (NDZ*8)
                     37:  
                     38: /*
                     39:  * Registers and bits
                     40:  */
                     41: 
                     42: /* Bits in dzlpr */
                     43: #define        BITS7   020
                     44: #define        BITS8   030
                     45: #define        TWOSB   040
                     46: #define        PENABLE 0100
                     47: #define        OPAR    0200
                     48: 
                     49: /* Bits in dzrbuf */
                     50: #define        DZ_PE   010000
                     51: #define        DZ_FE   020000
                     52: #define        DZ_DO   040000
                     53: 
                     54: /* Bits in dzcsr */
                     55: #define        DZ_CLR  020             /* Reset dz */
                     56: #define        DZ_MSE  040             /* Master Scan Enable */
                     57: #define        DZ_RIE  0100            /* Receiver Interrupt Enable */
                     58: #define        DZ_SAE  010000          /* Silo Alarm Enable */
                     59: #define        DZ_TIE  040000          /* Transmit Interrupt Enable */
                     60: #define        DZ_IEN  (DZ_MSE|DZ_RIE|DZ_TIE|DZ_SAE)
                     61: 
                     62: /* Flags for modem-control */
                     63: #define        DZ_ON   1
                     64: #define        DZ_OFF  0
                     65:  
                     66: int    dzstart(), dzxint(), dzdma();
                     67: int    ttrstrt();
                     68: struct tty dz_tty[NDZLINE];
                     69: int    dz_cnt = { NDZLINE };
                     70: int    dzact;
                     71: 
                     72: struct device {
                     73:        short   dzcsr;          /* control-status register */
                     74:        short   dzrbuf;         /* receiver buffer */
                     75: #define        dzlpr   dzrbuf          /* line parameter reg is write of dzrbuf */
                     76:        char    dztcr;          /* transmit control register */
                     77:        char    dzdtr;          /* data terminal ready */
                     78:        char    dztbuf;         /* transmit buffer */
                     79:        char    dzbrk;          /* break control */
                     80: #define        dzmsr   dzbrk           /* modem status register */
                     81: };
                     82: /*
                     83:  * Software copy of dzbrk since it isn't readable
                     84:  */
                     85: char   dz_brk[NDZ];
                     86: char   dzsoftCAR[NDZ];
                     87: 
                     88: /*
                     89:  * The dz doesn't interrupt on carrier transitions, so
                     90:  * we have to use a timer to watch it.
                     91:  */
                     92: char   dz_timer;               /* timer started? */
                     93: 
                     94: /*
                     95:  * Pdma structures for fast output code
                     96:  */
                     97: struct pdma dzpdma[NDZLINE];
                     98: 
                     99: char   dz_speeds[] =
                    100:        { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,0,0 };
                    101:  
                    102: dzprobe(reg)
                    103:        caddr_t reg;
                    104: {
                    105:        register int br, cvec;
                    106:        register struct device *dzaddr = (struct device *)reg;
                    107: 
                    108: #ifdef lint
                    109:        br = 0; cvec = br; br = cvec;
                    110: #endif
                    111:        dzaddr->dzcsr = DZ_TIE|DZ_MSE;
                    112:        dzaddr->dztcr = 1;              /* enable any line */
                    113:        DELAY(100000);
                    114:        dzaddr->dzcsr = DZ_CLR;         /* reset everything */
                    115:        if (cvec && cvec != 0x200)
                    116:                cvec -= 4;
                    117:        return (1);
                    118: }
                    119: 
                    120: dzattach(ui)
                    121:        register struct uba_device *ui;
                    122: {
                    123:        register struct pdma *pdp = &dzpdma[ui->ui_unit*8];
                    124:        register struct tty *tp = &dz_tty[ui->ui_unit*8];
                    125:        register int cntr;
                    126:        extern dzscan();
                    127: 
                    128:        for (cntr = 0; cntr < 8; cntr++) {
                    129:                pdp->p_addr = (struct device *)ui->ui_addr;
                    130:                pdp->p_arg = (int)tp;
                    131:                pdp->p_fcn = dzxint;
                    132:                pdp++, tp++;
                    133:        }
                    134:        dzsoftCAR[ui->ui_unit] = ui->ui_flags;
                    135:        if (dz_timer == 0) {
                    136:                dz_timer++;
                    137:                timeout(dzscan, (caddr_t)0, hz);
                    138:        }
                    139: }
                    140: 
                    141: /*ARGSUSED*/
                    142: dzopen(dev, flag)
                    143:        dev_t dev;
                    144: {
                    145:        register struct tty *tp;
                    146:        register int unit;
                    147:  
                    148:        unit = minor(dev);
                    149:        if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) {
                    150:                u.u_error = ENXIO;
                    151:                return;
                    152:        }
                    153:        tp = &dz_tty[unit];
                    154:        tp->t_addr = (caddr_t)&dzpdma[unit];
                    155:        tp->t_oproc = dzstart;
                    156:        tp->t_iproc = NULL;
                    157:        tp->t_state |= WOPEN;
                    158:        if ((tp->t_state & ISOPEN) == 0) {
                    159:                ttychars(tp);
                    160:                tp->t_ospeed = tp->t_ispeed = B300;
                    161:                tp->t_flags = ODDP|EVENP|ECHO;
                    162:                /* tp->t_state |= HUPCLS; */
                    163:                dzparam(unit);
                    164:        } else if (tp->t_state&XCLUDE && u.u_uid != 0) {
                    165:                u.u_error = EBUSY;
                    166:                return;
                    167:        }
                    168:        dzmodem(unit, DZ_ON);
                    169:        (void) spl5();
                    170:        while ((tp->t_state & CARR_ON) == 0) {
                    171:                tp->t_state |= WOPEN;
                    172:                sleep((caddr_t)&tp->t_rawq, TTIPRI);
                    173:        }
                    174:        (void) spl0();
                    175:        (*linesw[tp->t_line].l_open)(dev, tp);
                    176: }
                    177:  
                    178: /*ARGSUSED*/
                    179: dzclose(dev, flag)
                    180:        dev_t dev;
                    181: {
                    182:        register struct tty *tp;
                    183:        register int unit;
                    184:        int dz;
                    185:  
                    186:        unit = minor(dev);
                    187:        dz = unit >> 3;
                    188:        tp = &dz_tty[unit];
                    189:        (*linesw[tp->t_line].l_close)(tp);
                    190:        ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
                    191:            (dz_brk[dz] &= ~(1 << (unit&07)));
                    192:        if (tp->t_state & HUPCLS)
                    193:                dzmodem(unit, DZ_OFF);
                    194:        ttyclose(tp);
                    195: }
                    196:  
                    197: dzread(dev)
                    198:        dev_t dev;
                    199: {
                    200:        register struct tty *tp;
                    201:  
                    202:        tp = &dz_tty[minor(dev)];
                    203:        (*linesw[tp->t_line].l_read)(tp);
                    204: }
                    205:  
                    206: dzwrite(dev)
                    207:        dev_t dev;
                    208: {
                    209:        register struct tty *tp;
                    210:  
                    211:        tp = &dz_tty[minor(dev)];
                    212:        (*linesw[tp->t_line].l_write)(tp);
                    213: }
                    214:  
                    215: /*ARGSUSED*/
                    216: dzrint(dz)
                    217:        int dz;
                    218: {
                    219:        register struct tty *tp;
                    220:        register int c;
                    221:        register struct device *dzaddr;
                    222:        register struct tty *tp0;
                    223:        register int unit;
                    224:        int overrun = 0;
                    225:  
                    226:        if ((dzact & (1<<dz)) == 0)
                    227:                return;
                    228:        unit = dz * 8;
                    229:        dzaddr = dzpdma[unit].p_addr;
                    230:        tp0 = &dz_tty[unit];
                    231:        while ((c = dzaddr->dzrbuf) < 0) {      /* char present */
                    232:                tp = tp0 + ((c>>8)&07);
                    233:                if (tp >= &dz_tty[dz_cnt])
                    234:                        continue;
                    235:                if ((tp->t_state & ISOPEN) == 0) {
                    236:                        wakeup((caddr_t)&tp->t_rawq);
                    237:                        continue;
                    238:                }
                    239:                if (c&DZ_FE)
                    240:                        if (tp->t_flags & RAW)
                    241:                                c = 0;
                    242:                        else
                    243:                                c = tun.t_intrc;
                    244:                if (c&DZ_DO && overrun == 0) {
                    245:                        printf("dz%d: silo overflow\n", dz);
                    246:                        overrun = 1;
                    247:                }
                    248:                if (c&DZ_PE)    
                    249:                        if (((tp->t_flags & (EVENP|ODDP)) == EVENP)
                    250:                          || ((tp->t_flags & (EVENP|ODDP)) == ODDP))
                    251:                                continue;
                    252: #if NBK > 0
                    253:                if (tp->t_line == NETLDISC) {
                    254:                        c &= 0177;
                    255:                        BKINPUT(c, tp);
                    256:                } else
                    257: #endif
                    258:                        (*linesw[tp->t_line].l_rint)(c, tp);
                    259:        }
                    260: }
                    261:  
                    262: /*ARGSUSED*/
                    263: dzioctl(dev, cmd, addr, flag)
                    264:        dev_t dev;
                    265:        caddr_t addr;
                    266: {
                    267:        register struct tty *tp;
                    268:        register int unit = minor(dev);
                    269:        register int dz = unit >> 3;
                    270:  
                    271:        tp = &dz_tty[unit];
                    272:        cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
                    273:        if (cmd == 0)
                    274:                return;
                    275:        if (ttioctl(tp, cmd, addr, flag)) {
                    276:                if (cmd==TIOCSETP || cmd==TIOCSETN)
                    277:                        dzparam(unit);
                    278:        } else switch(cmd) {
                    279: 
                    280:        case TIOCSBRK:
                    281:                ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
                    282:                        (dz_brk[dz] |= 1 << (unit&07));
                    283:                break;
                    284:        case TIOCCBRK:
                    285:                ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
                    286:                        (dz_brk[dz] &= ~(1 << (unit&07)));
                    287:                break;
                    288:        case TIOCSDTR:
                    289:                dzmodem(unit, DZ_ON);
                    290:                break;
                    291:        case TIOCCDTR:
                    292:                dzmodem(unit, DZ_OFF);
                    293:                break;
                    294:        default:
                    295:                u.u_error = ENOTTY;
                    296:        }
                    297: }
                    298:  
                    299: dzparam(unit)
                    300:        register int unit;
                    301: {
                    302:        register struct tty *tp;
                    303:        register struct device *dzaddr;
                    304:        register int lpr;
                    305:  
                    306:        tp = &dz_tty[unit];
                    307:        dzaddr = dzpdma[unit].p_addr;
                    308:        dzaddr->dzcsr = DZ_IEN;
                    309:        dzact |= (1<<(unit>>3));
                    310:        if (tp->t_ispeed == 0) {
                    311:                dzmodem(unit, DZ_OFF);          /* hang up line */
                    312:                return;
                    313:        }
                    314:        lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07);
                    315:        if ((tp->t_local&LLITOUT) || (tp->t_flags&RAW))
                    316:                lpr |= BITS8;
                    317:        else
                    318:                lpr |= (BITS7|PENABLE);
                    319:        if ((tp->t_flags & EVENP) == 0)
                    320:                lpr |= OPAR;
                    321:        if (tp->t_ispeed == B110)
                    322:                lpr |= TWOSB;
                    323:        dzaddr->dzlpr = lpr;
                    324: }
                    325:  
                    326: dzxint(tp)
                    327:        register struct tty *tp;
                    328: {
                    329:        register struct pdma *dp;
                    330:        register s;
                    331:  
                    332:        s = spl5();             /* block pdma interrupts */
                    333:        dp = (struct pdma *)tp->t_addr;
                    334:        tp->t_state &= ~BUSY;
                    335:        if (tp->t_state & FLUSH)
                    336:                tp->t_state &= ~FLUSH;
                    337:        else
                    338:                ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf);
                    339:        if (tp->t_line)
                    340:                (*linesw[tp->t_line].l_start)(tp);
                    341:        else
                    342:                dzstart(tp);
                    343:        if (tp->t_outq.c_cc == 0 || (tp->t_state&BUSY)==0)
                    344:                dp->p_addr->dztcr &= ~(1 << (minor(tp->t_dev)&07));
                    345:        splx(s);
                    346: }
                    347: 
                    348: dzstart(tp)
                    349:        register struct tty *tp;
                    350: {
                    351:        register struct pdma *dp;
                    352:        register struct device *dzaddr;
                    353:        register int cc;
                    354:        int s;
                    355:  
                    356:        dp = (struct pdma *)tp->t_addr;
                    357:        dzaddr = dp->p_addr;
                    358:        s = spl5();
                    359:        if (tp->t_state & (TIMEOUT|BUSY|TTSTOP))
                    360:                goto out;
                    361:        if (tp->t_state&ASLEEP && tp->t_outq.c_cc <= TTLOWAT(tp)) {
                    362:                tp->t_state &= ~ASLEEP;
                    363:                if (tp->t_chan)
                    364:                        mcstart(tp->t_chan, (caddr_t)&tp->t_outq);
                    365:                else
                    366:                        wakeup((caddr_t)&tp->t_outq);
                    367:        }
                    368:        if (tp->t_outq.c_cc == 0)
                    369:                goto out;
                    370:        if (tp->t_flags&RAW || tp->t_local&LLITOUT)
                    371:                cc = ndqb(&tp->t_outq, 0);
                    372:        else {
                    373:                cc = ndqb(&tp->t_outq, 0200);
                    374:                if (cc == 0) {
                    375:                        cc = getc(&tp->t_outq);
                    376:                        timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6);
                    377:                        tp->t_state |= TIMEOUT;
                    378:                        goto out;
                    379:                }
                    380:        }
                    381:        tp->t_state |= BUSY;
                    382:        dp->p_end = dp->p_mem = tp->t_outq.c_cf;
                    383:        dp->p_end += cc;
                    384:        dzaddr->dztcr |= 1 << (minor(tp->t_dev) & 07);  /* force intr */
                    385: out:
                    386:        splx(s);
                    387: }
                    388:  
                    389: /*
                    390:  * Stop output on a line.
                    391:  */
                    392: /*ARGSUSED*/
                    393: dzstop(tp, flag)
                    394:        register struct tty *tp;
                    395: {
                    396:        register struct pdma *dp;
                    397:        register int s;
                    398: 
                    399:        dp = (struct pdma *)tp->t_addr;
                    400:        s = spl5();
                    401:        if (tp->t_state & BUSY) {
                    402:                dp->p_end = dp->p_mem;
                    403:                if ((tp->t_state&TTSTOP)==0)
                    404:                        tp->t_state |= FLUSH;
                    405:        }
                    406:        splx(s);
                    407: }
                    408:  
                    409: dzmodem(unit, flag)
                    410:        register int unit;
                    411: {
                    412:        register struct device *dzaddr;
                    413:        register char bit;
                    414:  
                    415:        dzaddr = dzpdma[unit].p_addr;
                    416:        bit = 1<<(unit&07);
                    417:        if (flag == DZ_OFF)
                    418:                dzaddr->dzdtr &= ~bit;
                    419:        else
                    420:                dzaddr->dzdtr |= bit;
                    421: }
                    422:  
                    423: dzscan()
                    424: {
                    425:        register i;
                    426:        register struct device *dzaddr;
                    427:        register bit;
                    428:        register struct tty *tp;
                    429:  
                    430:        for (i = 0; i < dz_cnt ; i++) {
                    431:                dzaddr = dzpdma[i].p_addr;
                    432:                if (dzaddr == 0)
                    433:                        continue;
                    434:                tp = &dz_tty[i];
                    435:                bit = 1<<(i&07);
                    436:                if ((dzsoftCAR[i>>3]&bit) || (dzaddr->dzmsr&bit)) {
                    437:                        /* carrier present */
                    438:                        if ((tp->t_state & CARR_ON) == 0) {
                    439:                                wakeup((caddr_t)&tp->t_rawq);
                    440:                                tp->t_state |= CARR_ON;
                    441:                        }
                    442:                } else {
                    443:                        if ((tp->t_state&CARR_ON) &&
                    444:                            (tp->t_local&LNOHANG)==0) {
                    445:                                /* carrier lost */
                    446:                                if (tp->t_state&ISOPEN) {
                    447:                                        gsignal(tp->t_pgrp, SIGHUP);
                    448:                                        gsignal(tp->t_pgrp, SIGCONT);
                    449:                                        dzaddr->dzdtr &= ~bit;
                    450:                                        flushtty(tp, FREAD|FWRITE);
                    451:                                }
                    452:                                tp->t_state &= ~CARR_ON;
                    453:                        }
                    454:                }
                    455:        }
                    456:        timeout(dzscan, (caddr_t)0, 2*hz);
                    457: }
                    458: 
                    459: dztimer()
                    460: {
                    461:        int dz;
                    462: 
                    463:        for (dz = 0; dz < NDZ; dz++)
                    464:                dzrint(dz);
                    465: }
                    466: 
                    467: /*
                    468:  * Reset state of driver if UBA reset was necessary.
                    469:  * Reset parameters and restart transmission on open lines.
                    470:  */
                    471: dzreset(uban)
                    472:        int uban;
                    473: {
                    474:        register int unit;
                    475:        register struct tty *tp;
                    476:        register struct uba_device *ui;
                    477: 
                    478:        for (unit = 0; unit < NDZLINE; unit++) {
                    479:                ui = dzinfo[unit >> 3];
                    480:                if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0)
                    481:                        continue;
                    482:                if (unit%8 == 0)
                    483:                        printf(" dz%d", unit>>3);
                    484:                tp = &dz_tty[unit];
                    485:                if (tp->t_state & (ISOPEN|WOPEN)) {
                    486:                        dzparam(unit);
                    487:                        dzmodem(unit, DZ_ON);
                    488:                        tp->t_state &= ~BUSY;
                    489:                        dzstart(tp);
                    490:                }
                    491:        }
                    492:        dztimer();
                    493: }
                    494: #endif

unix.superglobalmegacorp.com

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