Annotation of 42BSD/sys/vaxuba/dmf.c, revision 1.1.1.1

1.1       root        1: /*     dmf.c   6.1     83/07/29        */
                      2: 
                      3: #include "dmf.h"
                      4: #if NDMF > 0
                      5: /*
                      6:  * DMF32 driver
                      7:  *
                      8:  * TODO:
                      9:  *     test with modem
                     10:  *     load as much as possible into silo
                     11:  *     get correct numbers for receive silo parameter timeout
                     12:  *     use auto XON/XOFF
                     13:  *     test reset code
                     14:  *     test with more than one unit
                     15:  *     optimize for efficient DMA and dynamically
                     16:  *       decide between silo and DMA mode
                     17:  */
                     18: #include "../machine/pte.h"
                     19: 
                     20: #include "bk.h"
                     21: #include "../h/param.h"
                     22: #include "../h/conf.h"
                     23: #include "../h/dir.h"
                     24: #include "../h/user.h"
                     25: #include "../h/ioctl.h"
                     26: #include "../h/tty.h"
                     27: #include "../h/map.h"
                     28: #include "../h/buf.h"
                     29: #include "../h/vm.h"
                     30: #include "../h/bk.h"
                     31: #include "../h/clist.h"
                     32: #include "../h/file.h"
                     33: #include "../h/uio.h"
                     34: 
                     35: #include "../vaxuba/ubareg.h"
                     36: #include "../vaxuba/ubavar.h"
                     37: #include "../vaxuba/dmfreg.h"
                     38: 
                     39: /*
                     40:  * Definition of the driver for the auto-configuration program.
                     41:  */
                     42: int    dmfprobe(), dmfattach(), dmfrint(), dmfxint();
                     43: struct uba_device *dmfinfo[NDMF];
                     44: u_short        dmfstd[] = { 0 };
                     45: struct uba_driver dmfdriver =
                     46:        { dmfprobe, 0, dmfattach, 0, dmfstd, "dmf", dmfinfo };
                     47: 
                     48: /*
                     49:  * Local variables for the driver
                     50:  */
                     51: char   dmf_speeds[] =
                     52:        { 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 010, 012, 014, 016, 017, 0 };
                     53: 
                     54: struct tty dmf_tty[NDMF*8];
                     55: char   dmfsoftCAR[NDMF];
                     56: #ifndef lint
                     57: int    ndmf = NDMF*8;                  /* used by iostat */
                     58: #endif
                     59: int    dmfact;                         /* mask of active dmf's */
                     60: int    dmfstart(), ttrstrt();
                     61: 
                     62: #ifdef DMFDMA
                     63: /*
                     64:  * The clist space is mapped by the driver onto each UNIBUS.
                     65:  * The UBACVT macro converts a clist space address for unibus uban
                     66:  * into an i/o space address for the DMA routine.
                     67:  */
                     68: int    dmf_ubinfo[MAXNUBA];            /* info about allocated unibus map */
                     69: static int cbase[MAXNUBA];             /* base address in unibus map */
                     70: #define        UBACVT(x, uban)         (cbase[uban] + ((x)-(char *)cfree))
                     71: #endif
                     72: 
                     73: /*
                     74:  * Routine for configuration to set dmf interrupt.
                     75:  */
                     76: /*ARGSUSED*/
                     77: dmfprobe(reg, ctlr)
                     78:        caddr_t reg;
                     79:        int ctlr;
                     80: {
                     81:        register int br, cvec;          /* these are ``value-result'' */
                     82:        register struct dmfdevice *dmfaddr = (struct dmfdevice *)reg;
                     83: 
                     84: #ifdef lint
                     85:        br = 0; cvec = br; br = cvec;
                     86:        dmfxint(0); dmfrint(0);
                     87:        dmfsrint(); dmfsxint(); dmfdaint(); dmfdbint(); dmflint();
                     88: #endif
                     89:        br = 0x15;
                     90:        cvec = (uba_hd[numuba].uh_lastiv -= 4*8);
                     91:        dmfaddr->dmfccsr0 = cvec >> 2;
                     92:        /* NEED TO SAVE IT SOMEWHERE FOR OTHER DEVICES */
                     93:        return (sizeof (struct dmfdevice));
                     94: }
                     95: 
                     96: /*
                     97:  * Routine called to attach a dmf.
                     98:  */
                     99: dmfattach(ui)
                    100:        struct uba_device *ui;
                    101: {
                    102: 
                    103:        dmfsoftCAR[ui->ui_unit] = ui->ui_flags;
                    104: }
                    105: 
                    106: 
                    107: /*
                    108:  * Open a DMF32 line, mapping the clist onto the uba if this
                    109:  * is the first dmf on this uba.  Turn on this dmf if this is
                    110:  * the first use of it.
                    111:  */
                    112: /*ARGSUSED*/
                    113: dmfopen(dev, flag)
                    114:        dev_t dev;
                    115: {
                    116:        register struct tty *tp;
                    117:        register int unit, dmf;
                    118:        register struct dmfdevice *addr;
                    119:        register struct uba_device *ui;
                    120:        int s;
                    121: 
                    122:        unit = minor(dev);
                    123:        dmf = unit >> 3;
                    124:        if (unit >= NDMF*8 || (ui = dmfinfo[dmf])== 0 || ui->ui_alive == 0)
                    125:                return (ENXIO);
                    126:        tp = &dmf_tty[unit];
                    127:        if (tp->t_state&TS_XCLUDE && u.u_uid!=0)
                    128:                return (EBUSY);
                    129:        addr = (struct dmfdevice *)ui->ui_addr;
                    130:        tp->t_addr = (caddr_t)addr;
                    131:        tp->t_oproc = dmfstart;
                    132:        tp->t_state |= TS_WOPEN;
                    133:        /*
                    134:         * While setting up state for this uba and this dmf,
                    135:         * block uba resets which can clear the state.
                    136:         */
                    137:        s = spl5();
                    138: #ifdef DMFDMA
                    139:        if (dmf_ubinfo[ui->ui_ubanum] == 0) {
                    140:                dmf_ubinfo[ui->ui_ubanum] =
                    141:                    uballoc(ui->ui_ubanum, (caddr_t)cfree,
                    142:                        nclist*sizeof(struct cblock), 0);
                    143:                cbase[ui->ui_ubanum] = dmf_ubinfo[ui->ui_ubanum]&0x3ffff;
                    144:        }
                    145: #endif
                    146:        if ((dmfact&(1<<dmf)) == 0) {
                    147:                addr->dmfcsr |= DMF_IE;
                    148:                dmfact |= (1<<dmf);
                    149:                addr->dmfrsp = 1;       /* DON'T KNOW WHAT TO SET IT TO YET */
                    150:        }
                    151:        splx(s);
                    152:        /*
                    153:         * If this is first open, initialze tty state to default.
                    154:         */
                    155:        if ((tp->t_state&TS_ISOPEN) == 0) {
                    156:                ttychars(tp);
                    157:                if (tp->t_ispeed == 0) {
                    158:                        tp->t_ispeed = B300;
                    159:                        tp->t_ospeed = B300;
                    160:                        tp->t_flags = ODDP|EVENP|ECHO;
                    161:                }
                    162:                dmfparam(unit);
                    163:        }
                    164:        /*
                    165:         * Wait for carrier, then process line discipline specific open.
                    166:         */
                    167:        if ((dmfmctl(dev, DMF_ON, DMSET) & (DMF_CAR<<8)) ||
                    168:            (dmfsoftCAR[dmf] & (1<<(unit&07))))
                    169:                tp->t_state |= TS_CARR_ON;
                    170:        s = spl5();
                    171:        while ((tp->t_state & TS_CARR_ON) == 0) {
                    172:                tp->t_state |= TS_WOPEN;
                    173:                sleep((caddr_t)&tp->t_rawq, TTIPRI);
                    174:        }
                    175:        splx(s);
                    176:        return ((*linesw[tp->t_line].l_open)(dev, tp));
                    177: }
                    178: 
                    179: /*
                    180:  * Close a DMF32 line.
                    181:  */
                    182: /*ARGSUSED*/
                    183: dmfclose(dev, flag)
                    184:        dev_t dev;
                    185:        int flag;
                    186: {
                    187:        register struct tty *tp;
                    188:        register unit;
                    189: 
                    190:        unit = minor(dev);
                    191:        tp = &dmf_tty[unit];
                    192:        (*linesw[tp->t_line].l_close)(tp);
                    193:        (void) dmfmctl(unit, DMF_BRK, DMBIC);
                    194:        if (tp->t_state&TS_HUPCLS || (tp->t_state&TS_ISOPEN)==0)
                    195:                (void) dmfmctl(unit, DMF_OFF, DMSET);
                    196:        ttyclose(tp);
                    197: }
                    198: 
                    199: dmfread(dev, uio)
                    200:        dev_t dev;
                    201:        struct uio *uio;
                    202: {
                    203:        register struct tty *tp;
                    204: 
                    205:        tp = &dmf_tty[minor(dev)];
                    206:        return ((*linesw[tp->t_line].l_read)(tp, uio));
                    207: }
                    208: 
                    209: dmfwrite(dev, uio)
                    210:        dev_t dev;
                    211:        struct uio *uio;
                    212: {
                    213:        register struct tty *tp;
                    214: 
                    215:        tp = &dmf_tty[minor(dev)];
                    216:        return ((*linesw[tp->t_line].l_write)(tp, uio));
                    217: }
                    218: 
                    219: /*
                    220:  * DMF32 receiver interrupt.
                    221:  */
                    222: dmfrint(dmf)
                    223:        int dmf;
                    224: {
                    225:        register struct tty *tp;
                    226:        register c;
                    227:        register struct dmfdevice *addr;
                    228:        register struct tty *tp0;
                    229:        register struct uba_device *ui;
                    230:        int overrun = 0, s;
                    231: 
                    232:        ui = dmfinfo[dmf];
                    233:        if (ui == 0 || ui->ui_alive == 0)
                    234:                return;
                    235:        addr = (struct dmfdevice *)ui->ui_addr;
                    236:        tp0 = &dmf_tty[dmf<<3];
                    237:        /*
                    238:         * Loop fetching characters from the silo for this
                    239:         * dmf until there are no more in the silo.
                    240:         */
                    241:        while ((c = addr->dmfrbuf) < 0) {
                    242:                tp = tp0 + ((c>>8)&07);
                    243:                if (c & DMF_DSC) {
                    244:                        s = spl5();
                    245:                        addr->dmfcsr = DMF_IE | DMFIR_TBUF | ((c>>8)&07);
                    246:                        if (addr->dmfrms & DMF_CAR) {
                    247:                                if ((tp->t_state & TS_CARR_ON) == 0) {
                    248:                                        wakeup((caddr_t)&tp->t_rawq);
                    249:                                        tp->t_state |= TS_CARR_ON;
                    250:                                }
                    251:                        } else {
                    252:                                if (tp->t_state & TS_CARR_ON) {
                    253:                                        gsignal(tp->t_pgrp, SIGHUP);
                    254:                                        gsignal(tp->t_pgrp, SIGCONT);
                    255:                                        addr->dmfcsr = DMF_IE | DMFIR_LCR |
                    256:                                                ((c>>8)&07);
                    257:                                        addr->dmftms = 0;
                    258:                                        ttyflush(tp, FREAD|FWRITE);
                    259:                                }
                    260:                                tp->t_state &= ~TS_CARR_ON;
                    261:                        }
                    262:                        splx(s);
                    263:                        continue;
                    264:                }
                    265:                if ((tp->t_state&TS_ISOPEN)==0) {
                    266:                        wakeup((caddr_t)tp);
                    267:                        continue;
                    268:                }
                    269:                if (c & DMF_PE)
                    270:                        if ((tp->t_flags&(EVENP|ODDP))==EVENP
                    271:                         || (tp->t_flags&(EVENP|ODDP))==ODDP )
                    272:                                continue;
                    273:                if ((c & DMF_DO) && overrun == 0) {
                    274:                        printf("dmf%d: silo overflow\n", dmf);
                    275:                        overrun = 1;
                    276:                }
                    277:                if (c & DMF_FE)
                    278:                        /*
                    279:                         * At framing error (break) generate
                    280:                         * a null (in raw mode, for getty), or a
                    281:                         * interrupt (in cooked/cbreak mode).
                    282:                         */
                    283:                        if (tp->t_flags&RAW)
                    284:                                c = 0;
                    285:                        else
                    286:                                c = tp->t_intrc;
                    287: #if NBK > 0
                    288:                if (tp->t_line == NETLDISC) {
                    289:                        c &= 0177;
                    290:                        BKINPUT(c, tp);
                    291:                } else
                    292: #endif
                    293:                        (*linesw[tp->t_line].l_rint)(c, tp);
                    294:        }
                    295: }
                    296: 
                    297: /*
                    298:  * Ioctl for DMF32.
                    299:  */
                    300: /*ARGSUSED*/
                    301: dmfioctl(dev, cmd, data, flag)
                    302:        dev_t dev;
                    303:        caddr_t data;
                    304: {
                    305:        register struct tty *tp;
                    306:        register int unit = minor(dev);
                    307:        int error;
                    308:  
                    309:        tp = &dmf_tty[unit];
                    310:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
                    311:        if (error >= 0)
                    312:                return (error);
                    313:        error = ttioctl(tp, cmd, data, flag);
                    314:        if (error >= 0) {
                    315:                if (cmd == TIOCSETP || cmd == TIOCSETN)
                    316:                        dmfparam(unit);
                    317:                return (error);
                    318:        }
                    319:        switch (cmd) {
                    320: 
                    321:        case TIOCSBRK:
                    322:                (void) dmfmctl(dev, DMF_BRK, DMBIS);
                    323:                break;
                    324: 
                    325:        case TIOCCBRK:
                    326:                (void) dmfmctl(dev, DMF_BRK, DMBIC);
                    327:                break;
                    328: 
                    329:        case TIOCSDTR:
                    330:                (void) dmfmctl(dev, DMF_DTR|DMF_RTS, DMBIS);
                    331:                break;
                    332: 
                    333:        case TIOCCDTR:
                    334:                (void) dmfmctl(dev, DMF_DTR|DMF_RTS, DMBIC);
                    335:                break;
                    336: 
                    337:        case TIOCMSET:
                    338:                (void) dmfmctl(dev, dmtodmf(*(int *)data), DMSET);
                    339:                break;
                    340: 
                    341:        case TIOCMBIS:
                    342:                (void) dmfmctl(dev, dmtodmf(*(int *)data), DMBIS);
                    343:                break;
                    344: 
                    345:        case TIOCMBIC:
                    346:                (void) dmfmctl(dev, dmtodmf(*(int *)data), DMBIC);
                    347:                break;
                    348: 
                    349:        case TIOCMGET:
                    350:                *(int *)data = dmftodm(dmfmctl(dev, 0, DMGET));
                    351:                break;
                    352: 
                    353:        default:
                    354:                return (ENOTTY);
                    355:        }
                    356:        return (0);
                    357: }
                    358: 
                    359: dmtodmf(bits)
                    360:        register int bits;
                    361: {
                    362:        register int b;
                    363: 
                    364:        b = bits & 012;
                    365:        if (bits & DML_ST) b |= DMF_RATE;
                    366:        if (bits & DML_RTS) b |= DMF_RTS;
                    367:        if (bits & DML_USR) b |= DMF_USRW;
                    368:        return(b);
                    369: }
                    370: 
                    371: dmftodm(bits)
                    372:        register int bits;
                    373: {
                    374:        register int b;
                    375: 
                    376:        b = (bits & 012) | ((bits >> 7) & 0760) | DML_LE;
                    377:        if (bits & DMF_USRR) b |= DML_USR;
                    378:        if (bits & DMF_RTS) b |= DML_RTS;
                    379:        return(b);
                    380: }
                    381:  
                    382: 
                    383: /*
                    384:  * Set parameters from open or stty into the DMF hardware
                    385:  * registers.
                    386:  */
                    387: dmfparam(unit)
                    388:        register int unit;
                    389: {
                    390:        register struct tty *tp;
                    391:        register struct dmfdevice *addr;
                    392:        register int lpar, lcr;
                    393:        int s;
                    394: 
                    395:        tp = &dmf_tty[unit];
                    396:        addr = (struct dmfdevice *)tp->t_addr;
                    397:        /*
                    398:         * Block interrupts so parameters will be set
                    399:         * before the line interrupts.
                    400:         */
                    401:        s = spl5();
                    402:        addr->dmfcsr = (unit&07) | DMFIR_LCR | DMF_IE;
                    403:        if ((tp->t_ispeed)==0) {
                    404:                tp->t_state |= TS_HUPCLS;
                    405:                (void) dmfmctl(unit, DMF_OFF, DMSET);
                    406:                return;
                    407:        }
                    408:        lpar = (dmf_speeds[tp->t_ospeed]<<12) | (dmf_speeds[tp->t_ispeed]<<8);
                    409:        lcr = DMFLCR_ENA;
                    410:        if ((tp->t_ispeed) == B134)
                    411:                lpar |= BITS6|PENABLE;
                    412:        else if (tp->t_flags & (RAW|LITOUT))
                    413:                lpar |= BITS8;
                    414:        else {
                    415:                lpar |= BITS7|PENABLE;
                    416:                /* CHECK FOR XON/XOFF AND SET lcr |= DMF_AUTOX; */
                    417:        }
                    418:        if (tp->t_flags&EVENP)
                    419:                lpar |= EPAR;
                    420:        if ((tp->t_ospeed) == B110)
                    421:                lpar |= TWOSB;
                    422:        lpar |= (unit&07);
                    423:        addr->dmflpr = lpar;
                    424:        SETLCR(addr, lcr);
                    425:        splx(s);
                    426: }
                    427: 
                    428: /*
                    429:  * DMF32 transmitter interrupt.
                    430:  * Restart the idle line.
                    431:  */
                    432: dmfxint(dmf)
                    433:        int dmf;
                    434: {
                    435:        register struct tty *tp;
                    436:        register struct dmfdevice *addr;
                    437:        register struct uba_device *ui;
                    438:        register int unit, t;
                    439: #ifdef DMFDMA
                    440:        short cntr;
                    441:        int s;
                    442: #endif
                    443: 
                    444:        ui = dmfinfo[dmf];
                    445:        addr = (struct dmfdevice *)ui->ui_addr;
                    446:        while ((t = addr->dmfcsr) & DMF_TI) {
                    447:                unit = dmf*8 + ((t>>8)&07);
                    448:                tp = &dmf_tty[unit];
                    449:                tp->t_state &= ~TS_BUSY;
                    450:                if (t & DMF_NXM) {
                    451:                        printf("dmf%d: NXM line %d\n", dmf, unit&7);
                    452:                        /* SHOULD RESTART OR SOMETHING... */
                    453:                }
                    454:                if (tp->t_state&TS_FLUSH)
                    455:                        tp->t_state &= ~TS_FLUSH;
                    456: #ifdef DMFDMA
                    457:                else {
                    458:                        s = spl5();
                    459:                        addr->dmfcsr = DMFIR_TBUF | DMF_IE | (unit&07);
                    460:                        if (addr->dmftsc == 0) {
                    461:                                /*
                    462:                                 * Do arithmetic in a short to make up
                    463:                                 * for lost 16&17 bits.
                    464:                                 */
                    465:                                addr->dmfcsr = DMFIR_TBA | DMF_IE | (unit&07);
                    466:                                cntr = addr->dmftba -
                    467:                                    UBACVT(tp->t_outq.c_cf, ui->ui_ubanum);
                    468:                                ndflush(&tp->t_outq, (int)cntr);
                    469:                        }
                    470:                        splx(s);
                    471:                }
                    472: #endif
                    473:                if (tp->t_line)
                    474:                        (*linesw[tp->t_line].l_start)(tp);
                    475:                else
                    476:                        dmfstart(tp);
                    477:        }
                    478: }
                    479: 
                    480: /*
                    481:  * Start (restart) transmission on the given DMF32 line.
                    482:  */
                    483: dmfstart(tp)
                    484:        register struct tty *tp;
                    485: {
                    486:        register struct dmfdevice *addr;
                    487:        register int unit, nch;
                    488:        int s;
                    489: 
                    490:        unit = minor(tp->t_dev);
                    491:        unit &= 07;
                    492:        addr = (struct dmfdevice *)tp->t_addr;
                    493: 
                    494:        /*
                    495:         * Must hold interrupts in following code to prevent
                    496:         * state of the tp from changing.
                    497:         */
                    498:        s = spl5();
                    499:        /*
                    500:         * If it's currently active, or delaying, no need to do anything.
                    501:         */
                    502:        if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
                    503:                goto out;
                    504:        /*
                    505:         * If there are still characters in the silo,
                    506:         * just reenable the transmitter.
                    507:         */
                    508:        addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit;
                    509:        if (addr->dmftsc) {
                    510:                addr->dmfcsr = DMF_IE | DMFIR_LCR | unit;
                    511:                SETLCR(addr, addr->dmflcr|DMF_TE);
                    512:                tp->t_state |= TS_BUSY;
                    513:                goto out;
                    514:        }
                    515:        /*
                    516:         * If there are sleepers, and output has drained below low
                    517:         * water mark, wake up the sleepers.
                    518:         */
                    519:        if ((tp->t_state&TS_ASLEEP) && tp->t_outq.c_cc<=TTLOWAT(tp)) {
                    520:                tp->t_state &= ~TS_ASLEEP;
                    521:                wakeup((caddr_t)&tp->t_outq);
                    522:        }
                    523:        /*
                    524:         * Now restart transmission unless the output queue is
                    525:         * empty.
                    526:         */
                    527:        if (tp->t_outq.c_cc == 0)
                    528:                goto out;
                    529:        if (tp->t_flags & (RAW|LITOUT))
                    530:                nch = ndqb(&tp->t_outq, 0);
                    531:        else {
                    532:                nch = ndqb(&tp->t_outq, 0200);
                    533:                /*
                    534:                 * If first thing on queue is a delay process it.
                    535:                 */
                    536:                if (nch == 0) {
                    537:                        nch = getc(&tp->t_outq);
                    538:                        timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6);
                    539:                        tp->t_state |= TS_TIMEOUT;
                    540:                        goto out;
                    541:                }
                    542:        }
                    543:        /*
                    544:         * If characters to transmit, restart transmission.
                    545:         */
                    546:        if (nch) {
                    547: #ifdef DMFDMA
                    548:                addr->dmfcsr = DMF_IE | DMFIR_LCR | unit;
                    549:                SETLCR(addr, addr->dmflcr|DMF_TE);
                    550:                car = UBACVT(tp->t_outq.c_cf, dmfinfo[dmf]->ui_ubanum);
                    551:                addr->dmfcsr = DMF_IE | DMFIR_TBA | unit;
                    552:                addr->dmftba = car;
                    553:                addr->dmftcc = ((car>>2)&0xc000) | nch;
                    554: #else
                    555:                register char *cp = tp->t_outq.c_cf;
                    556:                register int i;
                    557: 
                    558:                nch = MIN(nch, DMF_SILOCNT);
                    559:                addr->dmfcsr = DMF_IE | DMFIR_LCR | unit;
                    560:                SETLCR(addr, addr->dmflcr|DMF_TE);
                    561:                addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit;
                    562:                for (i = 0; i < nch; i++)
                    563:                        addr->dmftbuf = *cp++;
                    564:                ndflush(&tp->t_outq, nch);
                    565: #endif
                    566:                tp->t_state |= TS_BUSY;
                    567:        }
                    568: out:
                    569:        splx(s);
                    570: }
                    571: 
                    572: /*
                    573:  * Stop output on a line, e.g. for ^S/^Q or output flush.
                    574:  */
                    575: /*ARGSUSED*/
                    576: dmfstop(tp, flag)
                    577:        register struct tty *tp;
                    578: {
                    579:        register struct dmfdevice *addr;
                    580:        register int unit, s;
                    581: 
                    582:        addr = (struct dmfdevice *)tp->t_addr;
                    583:        /*
                    584:         * Block input/output interrupts while messing with state.
                    585:         */
                    586:        s = spl5();
                    587:        if (tp->t_state & TS_BUSY) {
                    588:                /*
                    589:                 * Device is transmitting; stop output
                    590:                 * by selecting the line and disabling
                    591:                 * the transmitter.  If this is a flush
                    592:                 * request then flush the output silo,
                    593:                 * otherwise we will pick up where we
                    594:                 * left off by enabling the transmitter.
                    595:                 */
                    596:                unit = minor(tp->t_dev);
                    597:                addr->dmfcsr = DMFIR_LCR | (unit&07) | DMF_IE;
                    598:                SETLCR(addr, addr->dmflcr &~ DMF_TE);
                    599:                if ((tp->t_state&TS_TTSTOP)==0) {
                    600:                        tp->t_state |= TS_FLUSH;
                    601:                        SETLCR(addr, addr->dmflcr|DMF_FLUSH);
                    602:                } else
                    603:                        tp->t_state &= ~TS_BUSY;
                    604:        }
                    605:        splx(s);
                    606: }
                    607: 
                    608: /*
                    609:  * DMF32 modem control
                    610:  */
                    611: dmfmctl(dev, bits, how)
                    612:        dev_t dev;
                    613:        int bits, how;
                    614: {
                    615:        register struct dmfdevice *dmfaddr;
                    616:        register int unit, mbits, lcr;
                    617:        int s;
                    618: 
                    619:        unit = minor(dev);
                    620:        dmfaddr = (struct dmfdevice *)(dmf_tty[unit].t_addr);
                    621:        unit &= 07;
                    622:        s = spl5();
                    623:        dmfaddr->dmfcsr = DMF_IE | DMFIR_TBUF | unit;
                    624:        mbits = dmfaddr->dmfrms << 8;
                    625:        dmfaddr->dmfcsr = DMF_IE | DMFIR_LCR | unit;
                    626:        mbits |= dmfaddr->dmftms;
                    627:        lcr = dmfaddr->dmflcr;
                    628:        switch (how) {
                    629:        case DMSET:
                    630:                mbits = (mbits &0xff00) | bits;
                    631:                break;
                    632: 
                    633:        case DMBIS:
                    634:                mbits |= bits;
                    635:                break;
                    636: 
                    637:        case DMBIC:
                    638:                mbits &= ~bits;
                    639:                break;
                    640: 
                    641:        case DMGET:
                    642:                (void) splx(s);
                    643:                return(mbits);
                    644:        }
                    645:        if (mbits & DMF_BRK)
                    646:                lcr |= DMF_RBRK;
                    647:        else
                    648:                lcr &= ~DMF_RBRK;
                    649:        lcr = ((mbits & 037) << 8) | (lcr & 0xff);
                    650:        dmfaddr->dmfun.dmfirw = lcr;
                    651:        (void) splx(s);
                    652:        return(mbits);
                    653: }
                    654: 
                    655: /*
                    656:  * Reset state of driver if UBA reset was necessary.
                    657:  * Reset the csr, lpr, and lcr registers on open lines, and
                    658:  * restart transmitters.
                    659:  */
                    660: dmfreset(uban)
                    661:        int uban;
                    662: {
                    663:        register int dmf, unit;
                    664:        register struct tty *tp;
                    665:        register struct uba_device *ui;
                    666:        register struct dmfdevice *addr;
                    667:        int i;
                    668: 
                    669: #ifdef DMFDMA
                    670:        if (dmf_ubinfo[uban] == 0)
                    671:                return;
                    672:        dmf_ubinfo[uban] = uballoc(uban, (caddr_t)cfree,
                    673:            nclist*sizeof (struct cblock), 0);
                    674:        cbase[uban] = dmf_ubinfo[uban]&0x3ffff;
                    675: #endif
                    676:        for (dmf = 0; dmf < NDMF; dmf++) {
                    677:                ui = dmfinfo[dmf];
                    678:                if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban)
                    679:                        continue;
                    680:                printf(" dmf%d", dmf);
                    681:                addr = (struct dmfdevice *)ui->ui_addr;
                    682:                addr->dmfcsr = DMF_IE;
                    683:                addr->dmfrsp = 1;
                    684:                unit = dmf * 8;
                    685:                for (i = 0; i < 8; i++) {
                    686:                        tp = &dmf_tty[unit];
                    687:                        if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
                    688:                                dmfparam(unit);
                    689:                                (void) dmfmctl(unit, DMF_ON, DMSET);
                    690:                                tp->t_state &= ~TS_BUSY;
                    691:                                dmfstart(tp);
                    692:                        }
                    693:                        unit++;
                    694:                }
                    695:        }
                    696: }
                    697: 
                    698: /* stubs for interrupt routines for devices not yet supported */
                    699: 
                    700: dmfsrint() { printf("dmfsrint\n"); }
                    701: 
                    702: dmfsxint() { printf("dmfsxint\n"); }
                    703: 
                    704: dmfdaint() { printf("dmfdaint\n"); }
                    705: 
                    706: dmfdbint() { printf("dmfdbint\n"); }
                    707: 
                    708: dmflint() { printf("dmflint\n"); }
                    709: #endif

unix.superglobalmegacorp.com

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