Annotation of 41BSD/4.0.upgrade/sys/dev/dz.c, revision 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.