Annotation of 43BSD/sys/vaxuba/dmz.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1985, 1986 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  *
                      6:  *     @(#)dmz.c       7.1 (Berkeley) 6/5/86
                      7:  */
                      8: 
                      9: /*
                     10:  * DMZ-32 driver
                     11:  * HISTORY
                     12:  * 23-Apr-85  Joe Camaratta (jcc) at Siemens RTL
                     13:  *     Driver for DEC's DMZ32 24-line asynchronous multiplexor.
                     14:  *     Based on Chris Maloney's driver for DEC's DMF32
                     15:  *
                     16:  * 9-Aug-85    Mike Meyer (mwm) at ucb
                     17:  *     Mangled into shape for 4.3.
                     18:  */
                     19: 
                     20: #include "dmz.h"
                     21: #if NDMZ > 0
                     22: 
                     23: 
                     24: #include "../machine/pte.h"
                     25: 
                     26: 
                     27: #include "bk.h"
                     28: #include "uba.h"
                     29: #include "param.h"
                     30: #include "conf.h"
                     31: #include "dir.h"
                     32: #include "user.h"
                     33: #include "proc.h"
                     34: #include "ioctl.h"
                     35: #include "tty.h"
                     36: #include "map.h"
                     37: #include "buf.h"
                     38: #include "vm.h"
                     39: #include "bkmac.h"
                     40: #include "clist.h"
                     41: #include "file.h"
                     42: #include "uio.h"
                     43: #include "kernel.h"
                     44: #include "syslog.h"
                     45: 
                     46: #include "ubareg.h"
                     47: #include "ubavar.h"
                     48: #include "dmzreg.h"
                     49: #include "dmreg.h"
                     50: 
                     51: int dmzprobe(), dmzattach(), dmzrint(), dmzxint();
                     52: struct uba_device *dmzinfo[NDMZ];
                     53: u_short dmzstd[] = {0, 0};
                     54: struct uba_driver dmzdriver = {
                     55:        dmzprobe, 0, dmzattach, 0, dmzstd, "dmz", dmzinfo
                     56: };
                     57: 
                     58: #define        NDMZLINES       (NDMZ*24)
                     59: 
                     60: int ttrstrt();
                     61: struct tty dmz_tty[NDMZLINES];
                     62: 
                     63: int dmzsoftCAR[NDMZ];
                     64: 
                     65: struct {
                     66:        char dmz_state;         /* dmz state */
                     67:        int dmz_count;          /* dmz dma count */
                     68: } dmz_softc[NDMZ*24];
                     69: 
                     70: #define        ST_TXOFF        (0x01)  /* transmission turned off (^S) */
                     71: #define        ST_DMA          (0x02)  /* dma inprogress */
                     72: #define        ST_INBUSY       (0x04)  /* stop transmission in busy */
                     73: 
                     74: char dmz_speeds[] = {
                     75:        0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 010, 012, 014, 016, 017, 0 
                     76: };
                     77: 
                     78: #ifndef        PORTSELECTOR
                     79: #define        ISPEED  B9600
                     80: #define        IFLAGS  (EVENP|ODDP|ECHO)
                     81: #else
                     82: #define        ISPEED  B4800
                     83: #define        IFLAGS  (EVENP|ODDP)
                     84: #endif
                     85: 
                     86: #ifndef lint
                     87: int ndmz = NDMZLINES;          /* Used by pstat/iostat */
                     88: #endif
                     89: 
                     90: short dmzact[NDMZ];            /* Mask of active octets on the dmz */
                     91: int dmzstart();
                     92: 
                     93: /*
                     94:  * SILO_TIMEOUT represents the number of milliseconds characters can sit
                     95:  * in the input silo without causing an interrupt.  If data overruns or
                     96:  * slow XON/XOFF occur, set it lower but AT LEAST equal to 1.
                     97:  */
                     98: #define        SILO_TIMEOUT    (3)
                     99: 
                    100: /*
                    101:  * DO_DMA_COUNT represents the threshold of the number of output
                    102:  * characters beyond which the driver uses DMA mode.
                    103:  */
                    104: #define        DO_DMA_COUNT    (10)
                    105: 
                    106: #define        TRUE            (1)
                    107: #define        FALSE           (0)
                    108: 
                    109: int cbase[NUBA];               /* base address in unibus map */
                    110: int dmz_ubinfo[NUBA];          /* info about allocated unibus map */
                    111: 
                    112: #define        UBACVT(x, uban)     (cbase[uban] + ((x) - (char *)cfree))
                    113: 
                    114: /* These flags are for debugging purposes only */
                    115: int dmz_dma_on = 1;
                    116: 
                    117: dmzprobe(reg)
                    118:        caddr_t reg;
                    119: {
                    120:        register int br, cvec;
                    121:        register struct dmzdevice *dmz_addr;
                    122:        register unsigned int a;
                    123: 
                    124:        dmz_addr = (struct dmzdevice *)reg;
                    125: 
                    126: #ifdef lint
                    127:        br = 0; cvec = br; br = cvec; dmzxinta(0); dmzxintb(0); dmzxintc(0);
                    128:        dmzrinta(0); dmzrintb(0); dmzrintc(0);
                    129: #endif
                    130: 
                    131:        br = 0x15;
                    132: 
                    133:        a = dmz_addr->dmz_config;
                    134:        if (((a>>12) & ~DMZ_INTERFACE) != 0) {
                    135:                printf("        Unknown interface type\n");
                    136:                return (0);
                    137:        }
                    138:        if (((a>>8) & DMZ_NOC_MASK) != 3) {
                    139:                printf("        Not all octets are available\n");
                    140:                return (0);
                    141:        }
                    142: 
                    143:        cvec = (uba_hd[numuba].uh_lastiv -= 4 * 6);
                    144:        dmz_addr->dmz_config = cvec >> 2;
                    145: 
                    146:        return (sizeof(struct dmzdevice));
                    147: }
                    148: 
                    149: dmzattach(ui)
                    150:        struct uba_device *ui;
                    151: {
                    152:        dmzsoftCAR[ui->ui_unit] = ui->ui_flags;
                    153:        cbase[ui->ui_ubanum] = -1;
                    154: }
                    155: 
                    156: /* ARGSUSED */
                    157: dmzopen(device, flag)
                    158:        dev_t device;
                    159:        int flag;
                    160: {
                    161:        register struct tty *tp;
                    162:        register int unit, controller;
                    163:        register struct dmzdevice *dmz_addr;
                    164:        register struct uba_device *ui;
                    165:        int priority;
                    166:        int octet;
                    167: 
                    168:        unit = minor(device);
                    169:        controller = DMZ(unit);
                    170:        octet = OCTET(unit);
                    171: 
                    172:        if (unit >= NDMZLINES ||
                    173:            (ui = dmzinfo[controller]) == 0 ||
                    174:            ui->ui_alive == 0)
                    175:                return (ENXIO);
                    176: 
                    177:        tp = &dmz_tty[unit];
                    178: 
                    179:        if ((tp->t_state & TS_XCLUDE) && u.u_uid != 0)
                    180:                return (EBUSY);
                    181: 
                    182:        dmz_addr = (struct dmzdevice *)ui->ui_addr;
                    183:        tp->t_addr = (caddr_t)dmz_addr;
                    184:        tp->t_oproc = dmzstart;
                    185: 
                    186:        /*
                    187:         * Set up Unibus map registers.  Block uba resets, which can
                    188:         * clear the state.
                    189:         */
                    190:        priority = spl5();
                    191:        if (cbase[ui->ui_ubanum] == -1) {
                    192:                dmz_ubinfo[ui->ui_ubanum] = 
                    193:                        uballoc(ui->ui_ubanum, (caddr_t)cfree,
                    194:                                nclist * sizeof(struct cblock), 0);
                    195:                if (dmz_ubinfo[ui->ui_ubanum] == 0) {
                    196:                        splx(priority);
                    197:                        printf("dmz: insufficient unibus map regs\n");
                    198:                        return (ENOMEM);
                    199:                }
                    200:                cbase[ui->ui_ubanum] = UBAI_ADDR(dmz_ubinfo[ui->ui_ubanum]);
                    201:        }
                    202: 
                    203:        if ((dmzact[controller] & (1 << octet)) == 0) {
                    204:                dmz_addr->octet[octet].octet_csr |= DMZ_IE;
                    205:                dmzact[controller] |= 1 << octet;
                    206:                dmz_addr->octet[octet].octet_receive.octet_sato = SILO_TIMEOUT;
                    207:        }
                    208: 
                    209:        splx(priority);
                    210: 
                    211:        if ((tp->t_state & TS_ISOPEN) == 0) {
                    212:                ttychars(tp);
                    213: #ifndef PORTSELECTOR
                    214:                if (tp->t_ispeed == 0) {
                    215: #else
                    216:                        tp->t_state |= TS_HUPCLS;
                    217: #endif PORTSELECTOR
                    218:                        tp->t_ispeed = ISPEED;
                    219:                        tp->t_ospeed = ISPEED;
                    220:                        tp->t_flags = IFLAGS;
                    221: #ifndef PORTSELECTOR
                    222:                }
                    223: #endif PORTSELECTOR
                    224:                dmz_softc[unit].dmz_state = 0;
                    225:        }
                    226:        dmzparam(unit);
                    227: 
                    228:        /*
                    229:         * Wait for carrier, then process line discipline specific open.
                    230:         */
                    231:        if ((dmzmctl(unit, DMZ_ON, DMSET) & DMZ_CAR) ||
                    232:            (dmzsoftCAR[controller] & (1 << (unit % 24))))
                    233:                tp->t_state |= TS_CARR_ON;
                    234:        priority = spl5();      
                    235:        while ((tp->t_state & TS_CARR_ON) == 0) {
                    236:                tp->t_state |= TS_WOPEN;
                    237:                sleep((caddr_t) &tp->t_rawq, TTIPRI);
                    238:        }
                    239:        splx(priority);
                    240: 
                    241:        return ((*linesw[tp->t_line].l_open)(device, tp));
                    242: }
                    243: 
                    244: dmzparam(unit)
                    245:        register int unit;
                    246: {
                    247:        register struct tty *tp;
                    248:        register struct dmzdevice *dmz_addr;
                    249:        register int line_parameters;
                    250:        register int octet;
                    251:        int priority;
                    252: 
                    253:        octet = OCTET(unit);
                    254: 
                    255:        tp = &dmz_tty[unit];
                    256:        dmz_addr = (struct dmzdevice *)tp->t_addr;
                    257: 
                    258:        priority = spl5();
                    259:        if ((tp->t_ispeed) == 0) {
                    260:                tp->t_state |= TS_HUPCLS;
                    261:                (void) dmzmctl(unit, DMZ_OFF, DMSET);
                    262:                splx(priority);
                    263:                return;
                    264:        }
                    265: 
                    266:        line_parameters = (dmz_speeds[tp->t_ospeed] << 12) | (dmz_speeds[tp->t_ispeed] << 8);
                    267: 
                    268:        if ((tp->t_ispeed) == B134)
                    269:                line_parameters |= DMZ_6BT | DMZ_PEN;
                    270:        else if (tp->t_flags & (RAW | LITOUT | PASS8))
                    271:                line_parameters |= DMZ_8BT;
                    272:        else
                    273:                line_parameters |= DMZ_7BT | DMZ_PEN;
                    274: 
                    275:        if (tp->t_flags & EVENP)
                    276:                line_parameters |= DMZ_EPR;
                    277:        if ((tp->t_ospeed) == B110)
                    278:                line_parameters |= DMZ_SCD;
                    279: 
                    280:        line_parameters |= (unit & 07);
                    281: 
                    282:        dmz_addr->octet[octet].octet_lprm = line_parameters;
                    283:        splx(priority);
                    284: }
                    285: 
                    286: /* ARGSUSED */
                    287: dmzclose(device, flag)
                    288:        dev_t device;
                    289:        int flag;
                    290: {
                    291:        register struct  tty *tp;
                    292:        register int unit;
                    293: 
                    294:        unit = minor(device);
                    295:        tp = &dmz_tty[unit];
                    296:        (*linesw[tp->t_line].l_close)(tp);
                    297: 
                    298:        /*
                    299:         * Clear break, hang-up and close the modem.
                    300:         */
                    301:        (void) dmzmctl(unit, DMZ_BRK, DMBIC);
                    302:        if (tp->t_state & TS_HUPCLS || (tp->t_state & TS_ISOPEN) == 0)
                    303:                (void) dmzmctl(unit, DMZ_OFF, DMSET);
                    304:        ttyclose(tp);
                    305:        return;
                    306: }
                    307: 
                    308: dmzreset(uban)
                    309:        int uban;
                    310: {
                    311:        register int controller, unit;
                    312:        register struct tty *tp;
                    313:        register struct uba_device *ui;
                    314:        register struct dmzdevice *dmz_addr;
                    315:        int i;
                    316:        int octet;
                    317: 
                    318:        for (controller = 0; controller < NDMZ; controller++) {
                    319:                ui = dmzinfo[controller];
                    320:                if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban)
                    321:                        continue;
                    322:                printf("dmz%d ", controller);
                    323:                dmz_addr = (struct dmzdevice *) ui->ui_addr;
                    324: 
                    325:                if (dmz_ubinfo[uban]) {
                    326:                        dmz_ubinfo[uban] = uballoc(uban, (caddr_t)cfree,
                    327:                                nclist * sizeof(struct cblock), 0);
                    328:                        cbase[uban] = UBAI_ADDR(dmz_ubinfo[uban]);
                    329:                }
                    330: 
                    331:                for (octet = 0; octet < 3; octet++)
                    332:                        if ((dmzact[controller] & (1 << octet)) != 0) {
                    333:                                dmz_addr->octet[octet].octet_csr |= DMZ_IE;
                    334:                                dmz_addr->octet[octet].octet_receive.octet_sato = SILO_TIMEOUT;
                    335:                        }
                    336: 
                    337:                unit = controller * 24;
                    338: 
                    339:                /*
                    340:                 * If a unit is open or waiting for open to complete,
                    341:                 * reset it.
                    342:                 */
                    343:                for (i = 0; i < 24; i++) {
                    344:                        dmz_softc[unit].dmz_state = 0;
                    345:                        tp = &dmz_tty[unit];
                    346:                        if (tp->t_state & (TS_ISOPEN | TS_WOPEN)) {
                    347:                                dmzparam(unit);
                    348:                                (void) dmzmctl(unit, DMZ_ON, DMSET);
                    349:                                tp->t_state &= ~TS_BUSY;
                    350:                                dmzstart(tp);
                    351:                        }
                    352:                        unit++;
                    353:                }
                    354:        }
                    355:        return;
                    356: }
                    357: 
                    358: dmzread(device, uio)
                    359:        dev_t device;
                    360:        struct uio *uio;
                    361: {
                    362:        register struct tty *tp;
                    363:        int xstatus;
                    364: 
                    365:        tp = &dmz_tty[minor(device)];
                    366:        xstatus = (*linesw[tp->t_line].l_read)(tp, uio);
                    367:        return (xstatus);
                    368: }
                    369: 
                    370: dmzwrite(device, uio)
                    371:        dev_t device;
                    372:        struct uio *uio;
                    373: {
                    374:        register struct tty *tp;
                    375:        int xstatus;
                    376: 
                    377:        tp = &dmz_tty[minor(device)];
                    378:        xstatus = (*linesw[tp->t_line].l_write)(tp, uio);
                    379:        return (xstatus);
                    380: }
                    381: 
                    382: dmzrinta(controller)
                    383:        int controller;
                    384: {
                    385:        dmzrint(controller, 0);
                    386: }
                    387: 
                    388: dmzrintb(controller)
                    389:        int controller;
                    390: {
                    391:        dmzrint(controller, 1);
                    392: }
                    393: 
                    394: dmzrintc(controller)
                    395:        int controller;
                    396: {
                    397:        dmzrint(controller, 2);
                    398: }
                    399: 
                    400: dmzrint(controller, octet)
                    401:        int controller;
                    402:        register int octet;
                    403: {
                    404:        register struct tty *tp;
                    405:        register int character;
                    406:        register struct dmzdevice *dmz_addr;
                    407:        register struct tty *tp0;
                    408:        register int unit;
                    409:        register struct uba_device *ui;
                    410:        int overrun;
                    411: 
                    412:        overrun = 0;
                    413:        ui = dmzinfo[controller];
                    414:        if (ui == 0 || ui->ui_alive == 0)
                    415:                return;
                    416:        dmz_addr = (struct dmzdevice *) ui->ui_addr;
                    417:        tp0 = &dmz_tty[controller * 24];
                    418: 
                    419:        while ((character = dmz_addr->octet[octet].octet_receive.octet_rb) < 0) {
                    420:                unit = (character >> 8) & 07;   /* unit is bits 8-10 of rb */
                    421:                tp = tp0 + (octet * 8 + unit);
                    422: 
                    423:                if (character & DMZ_DSC) {
                    424:                        dmz_addr->octet[octet].octet_csr = DMZ_IE | IR_RMSTSC | unit;
                    425:                        if (dmz_addr->octet[octet].octet_rmstsc & DMZ_CAR)
                    426:                                (void)(*linesw[tp->t_line].l_modem)(tp, 1);
                    427:                        else if ((dmzsoftCAR[controller] &
                    428:                            (1 << (octet * 8 + unit))) == 0 &&
                    429:                            (*linesw[tp->t_line].l_modem)(tp, 0) == 0)
                    430:                                (void)dmzmctl(tp - dmz_tty, DMZ_OFF, DMSET);
                    431:                        continue;
                    432:                }
                    433: 
                    434:                if ((tp->t_state&TS_ISOPEN)==0) {
                    435:                        wakeup((caddr_t)&tp->t_rawq);
                    436: #ifdef PORTSELECTOR
                    437:                        if ((tp->t_state&TS_WOPEN) == 0)
                    438: #endif
                    439:                                continue;
                    440:                }
                    441: 
                    442:                if (character & DMZ_PE) {
                    443:                        if ((tp->t_flags & (EVENP | ODDP)) == EVENP ||
                    444:                            (tp->t_flags & (EVENP | ODDP)) == ODDP)
                    445:                                continue;
                    446:                }
                    447: 
                    448:                if ((character & DMZ_DO) && overrun == 0) {
                    449:                        log(LOG_WARNING, "dmz%d: silo overflow\n", controller);
                    450:                        overrun = 1;
                    451:                }
                    452: 
                    453:                if (character & DMZ_FE) {
                    454:                        if (tp->t_flags & RAW)
                    455:                                character = 0;
                    456:                        else
                    457:                                character = tp->t_intrc;
                    458:                }
                    459: 
                    460:                (*linesw[tp->t_line].l_rint)(character, tp);
                    461:        }
                    462: 
                    463:        return;
                    464: }
                    465: 
                    466: dmzxinta(controller)
                    467:        int controller;
                    468: {
                    469:        dmzxint(controller, 0);
                    470: }
                    471: 
                    472: dmzxintb(controller)
                    473:        int controller;
                    474: {
                    475:        dmzxint(controller, 1);
                    476: }
                    477: 
                    478: dmzxintc(controller)
                    479:        int controller;
                    480: {
                    481:        dmzxint(controller, 2);
                    482: }
                    483: 
                    484: dmzxint(controller, octet)
                    485:        int controller;
                    486:        register int octet;
                    487: {
                    488:        register struct tty *tp;
                    489:        register struct dmzdevice *dmz_addr;
                    490:        register struct uba_device *ui;
                    491:        register int unit, t;
                    492:        int priority;
                    493: 
                    494:        ui = dmzinfo[controller];
                    495:        dmz_addr = (struct dmzdevice *)ui->ui_addr;
                    496: 
                    497:        priority = spl5();
                    498: 
                    499:        while ((t = dmz_addr->octet[octet].octet_csr) & DMZ_TRDY) {
                    500:                unit = controller * 24 + (octet * 8 + ((t>>8) & 07));
                    501:                tp = &dmz_tty[unit];
                    502:                tp->t_state &= ~TS_BUSY;
                    503: 
                    504:                if (t & DMZ_NXM)
                    505:                        printf("dmz%d: NXM line %d\n", controller, 
                    506:                                octet * 8 + (unit & 07));
                    507: 
                    508:                if (tp->t_state & TS_FLUSH) {
                    509:                        tp->t_state &= ~TS_FLUSH;
                    510:                        dmz_addr->octet[octet].octet_csr = 
                    511:                                DMZ_IE | IR_LCTMR | (unit & 07);
                    512:                        dmz_addr->octet[octet].octet_lctmr = 
                    513:                                (dmz_addr->octet[octet].octet_lctmr | DMZ_TE);
                    514:                } else
                    515:                        if (dmz_softc[unit].dmz_state & ST_DMA)
                    516:                                ndflush(&tp->t_outq, dmz_softc[unit].dmz_count);
                    517:                dmz_softc[unit].dmz_state = 0;
                    518: 
                    519:                if (tp->t_line)
                    520:                        (*linesw[tp->t_line].l_start)(tp);
                    521:                else
                    522:                        dmzstart(tp);
                    523:        }
                    524: 
                    525:        splx(priority);
                    526:        return;
                    527: }
                    528: 
                    529: dmzstart(tp)
                    530:        register struct tty *tp;
                    531: {
                    532:        register struct dmzdevice *dmz_addr;
                    533:        register int unit, nch, room;
                    534:        int controller, octet;
                    535:        int priority, car, use_dma;
                    536:        register int i;
                    537:        register char *cp;
                    538: 
                    539:        unit = minor(tp->t_dev);
                    540:        controller = DMZ(unit);
                    541:        octet = OCTET(unit);
                    542:        dmz_addr = (struct dmzdevice *)tp->t_addr;
                    543: 
                    544:        priority = spl5();
                    545: 
                    546:        if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
                    547:                goto out;
                    548: 
                    549:        /*
                    550:         * If the transmitter has been disabled, reenable it.
                    551:         * If the transmitter was disabled before the xint (the
                    552:         * ST_INBUSY was still on), then reset the BUSY state and
                    553:         * we will wait for the interrupt.  If !TS_BUSY, we already
                    554:         * saw the interrupt so we can start another transmission.
                    555:         */
                    556:        if (dmz_softc[unit].dmz_state & ST_TXOFF) {
                    557:                dmz_addr->octet[octet].octet_csr = 
                    558:                        DMZ_IE | IR_LCTMR | (unit & 07);
                    559:                dmz_addr->octet[octet].octet_lctmr = 
                    560:                        (dmz_addr->octet[octet].octet_lctmr | DMZ_TE);
                    561:                dmz_softc[unit].dmz_state &= ~ST_TXOFF;
                    562:                if (dmz_softc[unit].dmz_state & ST_INBUSY) {
                    563:                        dmz_softc[unit].dmz_state &= ~ST_INBUSY;
                    564:                        tp->t_state |= TS_BUSY;
                    565:                        goto out;
                    566:                }
                    567:        }
                    568: 
                    569:        if (tp->t_outq.c_cc <= TTLOWAT(tp)) {
                    570:                if (tp->t_state & TS_ASLEEP) {
                    571:                        tp->t_state &= ~TS_ASLEEP;
                    572:                        wakeup((caddr_t)&tp->t_outq);
                    573:                }
                    574:                if (tp->t_wsel) {
                    575:                        selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
                    576:                        tp->t_wsel = 0;
                    577:                        tp->t_state &= ~TS_WCOLL;
                    578:                }
                    579:        }
                    580: 
                    581:        if (tp->t_outq.c_cc == 0)
                    582:                goto out;
                    583:        if (tp->t_flags & (RAW | LITOUT))
                    584:                nch = ndqb(&tp->t_outq, 0);
                    585:        else {
                    586:                nch = ndqb(&tp->t_outq, 0200);
                    587:                if (nch == 0) {
                    588:                        nch = getc(&tp->t_outq);
                    589:                        timeout(ttrstrt, (caddr_t)tp, (nch & 0x7f)+6);
                    590:                        tp->t_state |= TS_TIMEOUT;
                    591:                        goto out;
                    592:                }
                    593:        }
                    594: 
                    595:        /*
                    596:         * Should we use DMA or SILO mode?
                    597:         * If nch is greater than DO_DMA_COUNT then DMA.
                    598:         */
                    599:        if (nch) {
                    600:                dmz_addr->octet[octet].octet_csr = 
                    601:                        DMZ_IE | IR_LCTMR | (unit & 07);
                    602:                dmz_addr->octet[octet].octet_lctmr = 
                    603:                        (dmz_addr->octet[octet].octet_lctmr | DMZ_TE);
                    604:                tp->t_state |= TS_BUSY;
                    605: 
                    606:                use_dma = FALSE;
                    607:                room = DMZ_SIZ;
                    608: 
                    609:                if (nch > DO_DMA_COUNT)
                    610:                        use_dma = TRUE;
                    611:                
                    612:                if (use_dma && dmz_dma_on) {
                    613:                        car = UBACVT(tp->t_outq.c_cf, 
                    614:                                dmzinfo[controller]->ui_ubanum);
                    615:                        dmz_softc[unit].dmz_count = nch;
                    616:                        dmz_softc[unit].dmz_state |= ST_DMA;
                    617:                        dmz_addr->octet[octet].octet_csr = 
                    618:                                DMZ_IE | IR_TBA | (unit & 07);
                    619:                        dmz_addr->octet[octet].octet_tba = car;
                    620:                        dmz_addr->octet[octet].octet_tcc = 
                    621:                                ((car >> 2) & 0xc000) | nch;
                    622:                } else {
                    623:                        dmz_softc[unit].dmz_state &= ~ST_DMA;
                    624:                        cp = tp->t_outq.c_cf;
                    625:                        nch = MIN(nch, room);
                    626:                        dmz_addr->octet[octet].octet_csr = 
                    627:                                DMZ_IE | IR_TBUF | (unit & 07);
                    628:                        for (i = 0; i < nch; i++)
                    629:                                dmz_addr->octet[octet].octet_tbf = *cp++ ;
                    630:                        ndflush(&tp->t_outq, nch);
                    631:                }
                    632:        }
                    633: 
                    634: out:
                    635:        splx(priority);
                    636:        return;
                    637: }
                    638: 
                    639: /* ARGSUSED */
                    640: dmzstop(tp, flag)
                    641:        register struct tty *tp;
                    642: {
                    643:        register struct dmzdevice *dmz_addr;
                    644:        register int unit, priority, octet;
                    645: 
                    646:        priority = spl5();
                    647:        dmz_addr = (struct dmzdevice *) tp->t_addr;
                    648:        unit = minor(tp->t_dev);
                    649:        octet = OCTET(unit);
                    650: 
                    651:        dmz_addr->octet[octet].octet_csr = IR_LCTMR | (unit & 07) | DMZ_IE;
                    652:        dmz_addr->octet[octet].octet_lctmr = 
                    653:                (dmz_addr->octet[octet].octet_lctmr & ~DMZ_TE);
                    654:        dmz_softc[unit].dmz_state |= ST_TXOFF;
                    655:        if ((tp->t_state & TS_TTSTOP) == 0) {
                    656:                tp->t_state |= (TS_FLUSH | TS_BUSY);
                    657:                dmz_addr->octet[octet].octet_lctmr = 
                    658:                        (dmz_addr->octet[octet].octet_lctmr | DMZ_FLS);
                    659:        } else if (tp->t_state & TS_BUSY) {
                    660:                dmz_softc[unit].dmz_state |= ST_INBUSY;
                    661:                tp->t_state &= ~TS_BUSY;
                    662:        }
                    663: 
                    664:        splx(priority);
                    665:        return;
                    666: }
                    667: 
                    668: /* ARGSUSED */
                    669: dmzioctl(device, command, data, flag)
                    670:        dev_t device;
                    671:        caddr_t data;
                    672: {
                    673:        register struct tty *tp;
                    674:        register int unit;
                    675:        int error;
                    676: 
                    677:        unit = minor(device);
                    678:        tp = &dmz_tty[unit];
                    679: 
                    680:        error = (*linesw[tp->t_line].l_ioctl)(tp, command, data, flag);
                    681:        if (error >= 0)
                    682:                return (error);
                    683:        error = ttioctl(tp, command, data, flag);
                    684:        if (error >= 0) {
                    685:                if (command == TIOCSETP || command == TIOCSETN ||
                    686:                    command == TIOCLSET || command == TIOCLBIS ||
                    687:                    command == TIOCLBIC)
                    688:                        dmzparam(unit);
                    689:                return (error);
                    690:        }
                    691: 
                    692:        switch (command) {
                    693:                case TIOCSBRK:
                    694:                        (void) dmzmctl(unit, DMZ_BRK, DMBIS);
                    695:                        break;
                    696:                case TIOCCBRK:
                    697:                        (void) dmzmctl(unit, DMZ_BRK, DMBIC);
                    698:                        break;
                    699:                case TIOCSDTR:
                    700:                        (void) dmzmctl(unit, DMZ_DTR | DMZ_RTS, DMBIS);
                    701:                        break;
                    702:                case TIOCCDTR:
                    703:                        (void) dmzmctl(unit, DMZ_DTR | DMZ_RTS, DMBIC);
                    704:                        break;
                    705:                case TIOCMSET:
                    706:                        (void) dmzmctl(unit, dmtodmz(*(int *)data), DMSET);
                    707:                        break;
                    708:                case TIOCMBIS:
                    709:                        (void) dmzmctl(unit, dmtodmz(*(int *)data), DMBIS);
                    710:                        break;
                    711:                case TIOCMBIC:
                    712:                        (void) dmzmctl(unit, dmtodmz(*(int *)data), DMBIC);
                    713:                        break;
                    714:                case TIOCMGET:
                    715:                        *(int *)data = dmzmctl(unit, 0, DMGET);
                    716:                        break;
                    717:                default:
                    718:                        return (ENOTTY);
                    719:        }
                    720:        return (0);
                    721: }
                    722: 
                    723: dmzmctl(unit, bits, how)
                    724:        register int unit;
                    725:        int bits, how;
                    726: {
                    727:        register struct dmzdevice *dmz_addr;
                    728:        register int modem_status, line_control;
                    729:        int priority;
                    730:        int octet;
                    731: 
                    732:        octet = OCTET(unit);
                    733:        dmz_addr = (struct dmzdevice *) dmzinfo[DMZ(unit)]->ui_addr;
                    734: 
                    735:        priority = spl5();
                    736:        dmz_addr->octet[octet].octet_csr = DMZ_IE | IR_RMSTSC | (unit & 07);
                    737:        modem_status = dmz_addr->octet[octet].octet_rmstsc & 0xff00;
                    738: 
                    739:        dmz_addr->octet[octet].octet_csr = DMZ_IE | IR_LCTMR | (unit & 07);
                    740:        line_control = dmz_addr->octet[octet].octet_lctmr;
                    741: 
                    742: 
                    743:        switch (how) {
                    744:                case DMSET:
                    745:                        line_control = bits;
                    746:                        break;
                    747:                case DMBIS:
                    748:                        line_control |= bits;
                    749:                        break;
                    750:                case DMBIC:
                    751:                        line_control &= ~bits;
                    752:                        break;
                    753:                case DMGET:
                    754:                        (void) splx(priority);
                    755:                        return (dmztodm(modem_status, line_control));
                    756:        }
                    757: 
                    758:        dmz_addr->octet[octet].octet_csr =
                    759:                DMZ_IE | IR_LCTMR | (unit & 07);
                    760:        dmz_addr->octet[octet].octet_lctmr = line_control;
                    761: 
                    762:        splx(priority);
                    763:        return (modem_status);
                    764: }
                    765: 
                    766: /*
                    767:  * Routine to convert modem status from dm to dmz lctmr format.
                    768:  */
                    769: dmtodmz(bits)
                    770:        register int bits;
                    771: {
                    772:        register int lcr = DMZ_LCE;
                    773: 
                    774:        if (bits & DML_DTR)
                    775:                lcr |= DMZ_DTR;
                    776:        if (bits & DML_RTS)
                    777:                lcr |= DMZ_RTS;
                    778:        if (bits & DML_ST)
                    779:                lcr |= DMF_ST;
                    780:        if (bits & DML_USR)
                    781:                lcr |= DMZ_USRW;
                    782:        return (lcr);
                    783: }
                    784: 
                    785: /*
                    786:  * Routine to convert modem status from dmz receive modem status
                    787:  * and line control register to dm format.
                    788:  * If dmz user modem read bit set, set DML_USR.
                    789:  */
                    790: dmztodm(rms, lcr)
                    791:        register int rms, lcr;
                    792: {
                    793: 
                    794:        rms = ((rms & (DMZ_DSR|DMZ_RNG|DMZ_CAR|DMZ_CTS|DMF_SR)) >> 7) | 
                    795:                ((rms & DMZ_USRR) >> 1) | DML_LE;
                    796:        if (lcr & DMZ_DTR)
                    797:                rms |= DML_DTR;
                    798:        if (lcr & DMF_ST)
                    799:                rms |= DML_ST;
                    800:        if (lcr & DMZ_RTS)
                    801:                rms |= DML_RTS;
                    802:        return (rms);
                    803: }
                    804: #endif

unix.superglobalmegacorp.com

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