[BACK]Return to cz.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci

Annotation of sys/dev/pci/cz.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: cz.c,v 1.9 2003/10/03 16:44:51 miod Exp $ */
                      2: /*     $NetBSD: cz.c,v 1.15 2001/01/20 19:10:36 thorpej Exp $  */
                      3:
                      4: /*-
                      5:  * Copyright (c) 2000 Zembu Labs, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Authors: Jason R. Thorpe <thorpej@zembu.com>
                      9:  *          Bill Studenmund <wrstuden@zembu.com>
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *     This product includes software developed by Zembu Labs, Inc.
                     22:  * 4. Neither the name of Zembu Labs nor the names of its employees may
                     23:  *    be used to endorse or promote products derived from this software
                     24:  *    without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY ZEMBU LABS, INC. ``AS IS'' AND ANY EXPRESS
                     27:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAR-
                     28:  * RANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DIS-
                     29:  * CLAIMED.  IN NO EVENT SHALL ZEMBU LABS BE LIABLE FOR ANY DIRECT, INDIRECT,
                     30:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     31:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     32:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     33:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     34:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     35:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     36:  */
                     37:
                     38: /*
                     39:  * Cyclades-Z series multi-port serial adapter driver for NetBSD.
                     40:  *
                     41:  * Some notes:
                     42:  *
                     43:  *     - The Cyclades-Z has fully automatic hardware (and software!)
                     44:  *       flow control.  We only utilize RTS/CTS flow control here,
                     45:  *       and it is implemented in a very simplistic manner.  This
                     46:  *       may be an area of future work.
                     47:  *
                     48:  *     - The PLX can map the either the board's RAM or host RAM
                     49:  *       into the MIPS's memory window.  This would enable us to
                     50:  *       use less expensive (for us) memory reads/writes to host
                     51:  *       RAM, rather than time-consuming reads/writes to PCI
                     52:  *       memory space.  However, the PLX can only map a 0-128M
                     53:  *       window, so we would have to ensure that the DMA address
                     54:  *       of the host RAM fits there.  This is kind of a pain,
                     55:  *       so we just don't bother right now.
                     56:  *
                     57:  *     - In a perfect world, we would use the autoconfiguration
                     58:  *       mechanism to attach the TTYs that we find.  However,
                     59:  *       that leads to somewhat icky looking autoconfiguration
                     60:  *       messages (one for every TTY, up to 64 per board!).  So
                     61:  *       we don't do it that way, but assign minors as if there
                     62:  *       were the max of 64 ports per board.
                     63:  *
                     64:  *     - We don't bother with PPS support here.  There are so many
                     65:  *       ports, each with a large amount of buffer space, that the
                     66:  *       normal mode of operation is to poll the boards regularly
                     67:  *       (generally, every 20ms or so).  This makes this driver
                     68:  *       unsuitable for PPS, as the latency will be generally too
                     69:  *       high.
                     70:  */
                     71: /*
                     72:  * This driver inspired by the FreeBSD driver written by Brian J. McGovern
                     73:  * for FreeBSD 3.2.
                     74:  */
                     75:
                     76: #include <sys/param.h>
                     77: #include <sys/systm.h>
                     78: #include <sys/proc.h>
                     79: #include <sys/device.h>
                     80: #include <sys/malloc.h>
                     81: #include <sys/tty.h>
                     82: #include <sys/conf.h>
                     83: #include <sys/time.h>
                     84: #include <sys/kernel.h>
                     85: #include <sys/fcntl.h>
                     86: #include <sys/syslog.h>
                     87:
                     88: #include <dev/pci/pcireg.h>
                     89: #include <dev/pci/pcivar.h>
                     90: #include <dev/pci/pcidevs.h>
                     91: #include <dev/pci/czreg.h>
                     92:
                     93: #include <dev/pci/plx9060reg.h>
                     94: #include <dev/pci/plx9060var.h>
                     95:
                     96: #include <dev/microcode/cyclades/cyzfirm.h>
                     97:
                     98: #define        CZ_DRIVER_VERSION       0x20000411
                     99:
                    100: #define CZ_POLL_MS                     20
                    101:
                    102: /* These are the interrupts we always use. */
                    103: #define        CZ_INTERRUPTS                                                   \
                    104:        (C_IN_MDSR | C_IN_MRI | C_IN_MRTS | C_IN_MCTS | C_IN_TXBEMPTY | \
                    105:         C_IN_TXFEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM | C_IN_RXNNDT |     \
                    106:         C_IN_MDCD | C_IN_PR_ERROR | C_IN_FR_ERROR | C_IN_OVR_ERROR |   \
                    107:         C_IN_RXOFL | C_IN_IOCTLW | C_IN_RXBRK)
                    108:
                    109: /*
                    110:  * cztty_softc:
                    111:  *
                    112:  *     Per-channel (TTY) state.
                    113:  */
                    114: struct cztty_softc {
                    115:        struct cz_softc *sc_parent;
                    116:        struct tty *sc_tty;
                    117:
                    118:        struct timeout sc_diag_to;
                    119:
                    120:        int sc_channel;                 /* Also used to flag unattached chan */
                    121: #define CZTTY_CHANNEL_DEAD     -1
                    122:
                    123:        bus_space_tag_t sc_chan_st;     /* channel space tag */
                    124:        bus_space_handle_t sc_chan_sh;  /* channel space handle */
                    125:        bus_space_handle_t sc_buf_sh;   /* buffer space handle */
                    126:
                    127:        u_int sc_overflows,
                    128:              sc_parity_errors,
                    129:              sc_framing_errors,
                    130:              sc_errors;
                    131:
                    132:        int sc_swflags;
                    133:
                    134:        u_int32_t sc_rs_control_dtr,
                    135:                  sc_chanctl_hw_flow,
                    136:                  sc_chanctl_comm_baud,
                    137:                  sc_chanctl_rs_control,
                    138:                  sc_chanctl_comm_data_l,
                    139:                  sc_chanctl_comm_parity;
                    140: };
                    141:
                    142: /*
                    143:  * cz_softc:
                    144:  *
                    145:  *     Per-board state.
                    146:  */
                    147: struct cz_softc {
                    148:        struct device cz_dev;           /* generic device info */
                    149:        struct plx9060_config cz_plx;   /* PLX 9060 config info */
                    150:        bus_space_tag_t cz_win_st;      /* window space tag */
                    151:        bus_space_handle_t cz_win_sh;   /* window space handle */
                    152:        struct timeout cz_timeout;      /* timeout for polling-mode */
                    153:
                    154:        void *cz_ih;                    /* interrupt handle */
                    155:
                    156:        u_int32_t cz_mailbox0;          /* our MAILBOX0 value */
                    157:        int cz_nchannels;               /* number of channels */
                    158:        int cz_nopenchan;               /* number of open channels */
                    159:        struct cztty_softc *cz_ports;   /* our array of ports */
                    160:
                    161:        bus_addr_t cz_fwctl;            /* offset of firmware control */
                    162: };
                    163:
                    164: int    cz_match(struct device *, void *, void *);
                    165: void   cz_attach(struct device *, struct device *, void *);
                    166: int    cz_wait_pci_doorbell(struct cz_softc *, char *);
                    167:
                    168: struct cfattach cz_ca = {
                    169:        sizeof(struct cz_softc), cz_match, cz_attach
                    170: };
                    171:
                    172: void   cz_reset_board(struct cz_softc *);
                    173: int    cz_load_firmware(struct cz_softc *);
                    174:
                    175: int    cz_intr(void *);
                    176: void   cz_poll(void *);
                    177: int    cztty_transmit(struct cztty_softc *, struct tty *);
                    178: int    cztty_receive(struct cztty_softc *, struct tty *);
                    179:
                    180: struct cztty_softc * cztty_getttysoftc(dev_t dev);
                    181: int    cztty_findmajor(void);
                    182: int    cztty_major;
                    183: int    cztty_attached_ttys;
                    184: int    cz_timeout_ticks;
                    185:
                    186: cdev_decl(cztty);
                    187:
                    188: void    czttystart(struct tty *tp);
                    189: int    czttyparam(struct tty *tp, struct termios *t);
                    190: void    cztty_shutdown(struct cztty_softc *sc);
                    191: void   cztty_modem(struct cztty_softc *sc, int onoff);
                    192: void   cztty_break(struct cztty_softc *sc, int onoff);
                    193: void   tiocm_to_cztty(struct cztty_softc *sc, u_long how, int ttybits);
                    194: int    cztty_to_tiocm(struct cztty_softc *sc);
                    195: void   cztty_diag(void *arg);
                    196:
                    197: struct cfdriver cz_cd = {
                    198:        0, "cz", DV_TTY
                    199: };
                    200:
                    201: /*
                    202:  * Macros to read and write the PLX.
                    203:  */
                    204: #define        CZ_PLX_READ(cz, reg)                                            \
                    205:        bus_space_read_4((cz)->cz_plx.plx_st, (cz)->cz_plx.plx_sh, (reg))
                    206: #define        CZ_PLX_WRITE(cz, reg, val)                                      \
                    207:        bus_space_write_4((cz)->cz_plx.plx_st, (cz)->cz_plx.plx_sh,     \
                    208:            (reg), (val))
                    209:
                    210: /*
                    211:  * Macros to read and write the FPGA.  We must already be in the FPGA
                    212:  * window for this.
                    213:  */
                    214: #define        CZ_FPGA_READ(cz, reg)                                           \
                    215:        bus_space_read_4((cz)->cz_win_st, (cz)->cz_win_sh, (reg))
                    216: #define        CZ_FPGA_WRITE(cz, reg, val)                                     \
                    217:        bus_space_write_4((cz)->cz_win_st, (cz)->cz_win_sh, (reg), (val))
                    218:
                    219: /*
                    220:  * Macros to read and write the firmware control structures in board RAM.
                    221:  */
                    222: #define        CZ_FWCTL_READ(cz, off)                                          \
                    223:        bus_space_read_4((cz)->cz_win_st, (cz)->cz_win_sh,              \
                    224:            (cz)->cz_fwctl + (off))
                    225:
                    226: #define        CZ_FWCTL_WRITE(cz, off, val)                                    \
                    227:        bus_space_write_4((cz)->cz_win_st, (cz)->cz_win_sh,             \
                    228:            (cz)->cz_fwctl + (off), (val))
                    229:
                    230: /*
                    231:  * Convenience macros for cztty routines.  PLX window MUST be to RAM.
                    232:  */
                    233: #define CZTTY_CHAN_READ(sc, off)                                       \
                    234:        bus_space_read_4((sc)->sc_chan_st, (sc)->sc_chan_sh, (off))
                    235:
                    236: #define CZTTY_CHAN_WRITE(sc, off, val)                                 \
                    237:        bus_space_write_4((sc)->sc_chan_st, (sc)->sc_chan_sh,           \
                    238:            (off), (val))
                    239:
                    240: #define CZTTY_BUF_READ(sc, off)                                                \
                    241:        bus_space_read_4((sc)->sc_chan_st, (sc)->sc_buf_sh, (off))
                    242:
                    243: #define CZTTY_BUF_WRITE(sc, off, val)                                  \
                    244:        bus_space_write_4((sc)->sc_chan_st, (sc)->sc_buf_sh,            \
                    245:            (off), (val))
                    246:
                    247: /*
                    248:  * Convenience macros.
                    249:  */
                    250: #define        CZ_WIN_RAM(cz)                                                  \
                    251: do {                                                                   \
                    252:        CZ_PLX_WRITE((cz), PLX_LAS0BA, LOCAL_ADDR0_RAM);                \
                    253:        delay(100);                                                     \
                    254: } while (0)
                    255:
                    256: #define        CZ_WIN_FPGA(cz)                                                 \
                    257: do {                                                                   \
                    258:        CZ_PLX_WRITE((cz), PLX_LAS0BA, LOCAL_ADDR0_FPGA);               \
                    259:        delay(100);                                                     \
                    260: } while (0)
                    261:
                    262: /*****************************************************************************
                    263:  * Cyclades-Z controller code starts here...
                    264:  *****************************************************************************/
                    265:
                    266: /*
                    267:  * cz_match:
                    268:  *
                    269:  *     Determine if the given PCI device is a Cyclades-Z board.
                    270:  */
                    271: int
                    272: cz_match(parent, match, aux)
                    273:        struct device *parent;
                    274:        void *match, *aux;
                    275: {
                    276:        struct pci_attach_args *pa = aux;
                    277:
                    278:        if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_CYCLADES &&
                    279:            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CYCLADES_CYCLOMZ_2)
                    280:                return (1);
                    281:        return (0);
                    282: }
                    283:
                    284: /*
                    285:  * cz_attach:
                    286:  *
                    287:  *     A Cyclades-Z board was found; attach it.
                    288:  */
                    289: void
                    290: cz_attach(parent, self, aux)
                    291:        struct device *parent, *self;
                    292:        void *aux;
                    293: {
                    294:        struct cz_softc *cz = (void *) self;
                    295:        struct pci_attach_args *pa = aux;
                    296:        pci_chipset_tag_t pc = pa->pa_pc;
                    297:        pci_intr_handle_t ih;
                    298:        const char *intrstr = NULL;
                    299:        struct cztty_softc *sc;
                    300:        struct tty *tp;
                    301:        int i;
                    302:
                    303:        cz->cz_plx.plx_pc = pa->pa_pc;
                    304:        cz->cz_plx.plx_tag = pa->pa_tag;
                    305:
                    306:        if (pci_mapreg_map(pa, PLX_PCI_RUNTIME_MEMADDR,
                    307:            PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
                    308:            &cz->cz_plx.plx_st, &cz->cz_plx.plx_sh, NULL, NULL, 0) != 0) {
                    309:                printf(": unable to map PLX registers\n");
                    310:                return;
                    311:        }
                    312:        if (pci_mapreg_map(pa, PLX_PCI_LOCAL_ADDR0,
                    313:            PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
                    314:            &cz->cz_win_st, &cz->cz_win_sh, NULL, NULL, 0) != 0) {
                    315:                printf(": unable to map device window\n");
                    316:                return;
                    317:        }
                    318:
                    319:        cz->cz_mailbox0 = CZ_PLX_READ(cz, PLX_MAILBOX0);
                    320:        cz->cz_nopenchan = 0;
                    321:
                    322:        /*
                    323:         * Make sure that the board is completely stopped.
                    324:         */
                    325:        CZ_WIN_FPGA(cz);
                    326:        CZ_FPGA_WRITE(cz, FPGA_CPU_STOP, 0);
                    327:
                    328:        /*
                    329:         * Load the board's firmware.
                    330:         */
                    331:        if (cz_load_firmware(cz) != 0)
                    332:                return;
                    333:
                    334:        /*
                    335:         * Now that we're ready to roll, map and establish the interrupt
                    336:         * handler.
                    337:         */
                    338:        if (pci_intr_map(pa, &ih) != 0) {
                    339:                /*
                    340:                 * The common case is for Cyclades-Z boards to run
                    341:                 * in polling mode, and thus not have an interrupt
                    342:                 * mapped for them.  Don't bother reporting that
                    343:                 * the interrupt is not mappable, since this isn't
                    344:                 * really an error.
                    345:                 */
                    346:                cz->cz_ih = NULL;
                    347:                goto polling_mode;
                    348:        } else {
                    349:                intrstr = pci_intr_string(pa->pa_pc, ih);
                    350:                cz->cz_ih = pci_intr_establish(pc, ih, IPL_TTY,
                    351:                            cz_intr, cz, cz->cz_dev.dv_xname);
                    352:        }
                    353:        if (cz->cz_ih == NULL) {
                    354:                printf(": unable to establish interrupt");
                    355:                if (intrstr != NULL)
                    356:                        printf(" at %s", intrstr);
                    357:                printf("\n");
                    358:                /* We will fall-back on polling mode. */
                    359:        } else
                    360:                printf(": %s\n", intrstr);
                    361:
                    362:  polling_mode:
                    363:        if (cz->cz_ih == NULL) {
                    364:                timeout_set(&cz->cz_timeout, cz_poll, cz);
                    365:                if (cz_timeout_ticks == 0)
                    366:                        cz_timeout_ticks = max(1, hz * CZ_POLL_MS / 1000);
                    367:                printf("%s: polling mode, %d ms interval (%d tick%s)\n",
                    368:                    cz->cz_dev.dv_xname, CZ_POLL_MS, cz_timeout_ticks,
                    369:                    cz_timeout_ticks == 1 ? "" : "s");
                    370:        }
                    371:
                    372:        if (cztty_major == 0)
                    373:                cztty_major = cztty_findmajor();
                    374:        /*
                    375:         * Allocate sufficient pointers for the children and
                    376:         * attach them.  Set all ports to a reasonable initial
                    377:         * configuration while we're at it:
                    378:         *
                    379:         *      disabled
                    380:         *      8N1
                    381:         *      default baud rate
                    382:         *      hardware flow control.
                    383:         */
                    384:        CZ_WIN_RAM(cz);
                    385:
                    386:        if (cz->cz_nchannels == 0) {
                    387:                /* No channels?  No more work to do! */
                    388:                return;
                    389:        }
                    390:
                    391:        cz->cz_ports = malloc(sizeof(struct cztty_softc) * cz->cz_nchannels,
                    392:            M_DEVBUF, M_WAITOK);
                    393:        cztty_attached_ttys += cz->cz_nchannels;
                    394:        memset(cz->cz_ports, 0,
                    395:            sizeof(struct cztty_softc) * cz->cz_nchannels);
                    396:
                    397:        for (i = 0; i < cz->cz_nchannels; i++) {
                    398:                sc = &cz->cz_ports[i];
                    399:
                    400:                sc->sc_channel = i;
                    401:                sc->sc_chan_st = cz->cz_win_st;
                    402:                sc->sc_parent = cz;
                    403:
                    404:                if (bus_space_subregion(cz->cz_win_st, cz->cz_win_sh,
                    405:                    cz->cz_fwctl + ZFIRM_CHNCTL_OFF(i, 0),
                    406:                    ZFIRM_CHNCTL_SIZE, &sc->sc_chan_sh)) {
                    407:                        printf("%s: unable to subregion channel %d control\n",
                    408:                            cz->cz_dev.dv_xname, i);
                    409:                        sc->sc_channel = CZTTY_CHANNEL_DEAD;
                    410:                        continue;
                    411:                }
                    412:                if (bus_space_subregion(cz->cz_win_st, cz->cz_win_sh,
                    413:                    cz->cz_fwctl + ZFIRM_BUFCTL_OFF(i, 0),
                    414:                    ZFIRM_BUFCTL_SIZE, &sc->sc_buf_sh)) {
                    415:                        printf("%s: unable to subregion channel %d buffer\n",
                    416:                            cz->cz_dev.dv_xname, i);
                    417:                        sc->sc_channel = CZTTY_CHANNEL_DEAD;
                    418:                        continue;
                    419:                }
                    420:
                    421:                timeout_set(&sc->sc_diag_to, cztty_diag, sc);
                    422:
                    423:                tp = ttymalloc();
                    424:                tp->t_dev = makedev(cztty_major,
                    425:                    (cz->cz_dev.dv_unit * ZFIRM_MAX_CHANNELS) + i);
                    426:                tp->t_oproc = czttystart;
                    427:                tp->t_param = czttyparam;
                    428:
                    429:                sc->sc_tty = tp;
                    430:
                    431:                CZTTY_CHAN_WRITE(sc, CHNCTL_OP_MODE, C_CH_DISABLE);
                    432:                CZTTY_CHAN_WRITE(sc, CHNCTL_INTR_ENABLE, CZ_INTERRUPTS);
                    433:                CZTTY_CHAN_WRITE(sc, CHNCTL_SW_FLOW, 0);
                    434:                CZTTY_CHAN_WRITE(sc, CHNCTL_FLOW_XON, 0x11);
                    435:                CZTTY_CHAN_WRITE(sc, CHNCTL_FLOW_XOFF, 0x13);
                    436:                CZTTY_CHAN_WRITE(sc, CHNCTL_COMM_BAUD, TTYDEF_SPEED);
                    437:                CZTTY_CHAN_WRITE(sc, CHNCTL_COMM_PARITY, C_PR_NONE);
                    438:                CZTTY_CHAN_WRITE(sc, CHNCTL_COMM_DATA_L, C_DL_CS8 | C_DL_1STOP);
                    439:                CZTTY_CHAN_WRITE(sc, CHNCTL_COMM_FLAGS, 0);
                    440:                CZTTY_CHAN_WRITE(sc, CHNCTL_HW_FLOW, C_RS_CTS | C_RS_RTS);
                    441:                CZTTY_CHAN_WRITE(sc, CHNCTL_RS_CONTROL, 0);
                    442:        }
                    443: }
                    444:
                    445: /*
                    446:  * cz_reset_board:
                    447:  *
                    448:  *     Reset the board via the PLX.
                    449:  */
                    450: void
                    451: cz_reset_board(struct cz_softc *cz)
                    452: {
                    453:        u_int32_t reg;
                    454:
                    455:        reg = CZ_PLX_READ(cz, PLX_CONTROL);
                    456:        CZ_PLX_WRITE(cz, PLX_CONTROL, reg | CONTROL_SWR);
                    457:        delay(1000);
                    458:
                    459:        CZ_PLX_WRITE(cz, PLX_CONTROL, reg);
                    460:        delay(1000);
                    461:
                    462:        /* Now reload the PLX from its EEPROM. */
                    463:        reg = CZ_PLX_READ(cz, PLX_CONTROL);
                    464:        CZ_PLX_WRITE(cz, PLX_CONTROL, reg | CONTROL_RELOADCFG);
                    465:        delay(1000);
                    466:        CZ_PLX_WRITE(cz, PLX_CONTROL, reg);
                    467: }
                    468:
                    469: /*
                    470:  * cz_load_firmware:
                    471:  *
                    472:  *     Load the ZFIRM firmware into the board's RAM and start it
                    473:  *     running.
                    474:  */
                    475: int
                    476: cz_load_firmware(struct cz_softc *cz)
                    477: {
                    478:        struct zfirm_header *zfh;
                    479:        struct zfirm_config *zfc;
                    480:        struct zfirm_block *zfb, *zblocks;
                    481:        const u_int8_t *cp;
                    482:        const char *board;
                    483:        u_int32_t fid;
                    484:        int i, j, nconfigs, nblocks, nbytes;
                    485:
                    486:        zfh = (struct zfirm_header *) cycladesz_firmware;
                    487:
                    488:        /* Find the config header. */
                    489:        if (letoh32(zfh->zfh_configoff) & (sizeof(u_int32_t) - 1)) {
                    490:                printf("%s: bad ZFIRM config offset: 0x%x\n",
                    491:                    cz->cz_dev.dv_xname, letoh32(zfh->zfh_configoff));
                    492:                return (EIO);
                    493:        }
                    494:        zfc = (struct zfirm_config *)(cycladesz_firmware +
                    495:            letoh32(zfh->zfh_configoff));
                    496:        nconfigs = letoh32(zfh->zfh_nconfig);
                    497:
                    498:        /* Locate the correct configuration for our board. */
                    499:        for (i = 0; i < nconfigs; i++, zfc++) {
                    500:                if (letoh32(zfc->zfc_mailbox) == cz->cz_mailbox0 &&
                    501:                    letoh32(zfc->zfc_function) == ZFC_FUNCTION_NORMAL)
                    502:                        break;
                    503:        }
                    504:        if (i == nconfigs) {
                    505:                printf("%s: unable to locate config header\n",
                    506:                    cz->cz_dev.dv_xname);
                    507:                return (EIO);
                    508:        }
                    509:
                    510:        nblocks = letoh32(zfc->zfc_nblocks);
                    511:        zblocks = (struct zfirm_block *)(cycladesz_firmware +
                    512:            letoh32(zfh->zfh_blockoff));
                    513:
                    514:        /*
                    515:         * 8Zo ver. 1 doesn't have an FPGA.  Load it on all others if
                    516:         * necessary.
                    517:         */
                    518:        if (cz->cz_mailbox0 != MAILBOX0_8Zo_V1
                    519: #if 0
                    520:            && ((CZ_PLX_READ(cz, PLX_CONTROL) & CONTROL_FPGA_LOADED) == 0)
                    521: #endif
                    522:                                                                ) {
                    523: #ifdef CZ_DEBUG
                    524:                printf("%s: Loading FPGA...", cz->cz_dev.dv_xname);
                    525: #endif
                    526:                CZ_WIN_FPGA(cz);
                    527:                for (i = 0; i < nblocks; i++) {
                    528:                        /* zfb = zblocks + letoh32(zfc->zfc_blocklist[i]) ?? */
                    529:                        zfb = &zblocks[letoh32(zfc->zfc_blocklist[i])];
                    530:                        if (letoh32(zfb->zfb_type) == ZFB_TYPE_FPGA) {
                    531:                                nbytes = letoh32(zfb->zfb_size);
                    532:                                cp = &cycladesz_firmware[
                    533:                                    letoh32(zfb->zfb_fileoff)];
                    534:                                for (j = 0; j < nbytes; j++, cp++) {
                    535:                                        bus_space_write_1(cz->cz_win_st,
                    536:                                            cz->cz_win_sh, 0, *cp);
                    537:                                        /* FPGA needs 30-100us to settle. */
                    538:                                        delay(10);
                    539:                                }
                    540:                        }
                    541:                }
                    542: #ifdef CZ_DEBUG
                    543:                printf("done\n");
                    544: #endif
                    545:        }
                    546:
                    547:        /* Now load the firmware. */
                    548:        CZ_WIN_RAM(cz);
                    549:
                    550:        for (i = 0; i < nblocks; i++) {
                    551:                /* zfb = zblocks + letoh32(zfc->zfc_blocklist[i]) ?? */
                    552:                zfb = &zblocks[letoh32(zfc->zfc_blocklist[i])];
                    553:                if (letoh32(zfb->zfb_type) == ZFB_TYPE_FIRMWARE) {
                    554:                        const u_int32_t *lp;
                    555:                        u_int32_t ro = letoh32(zfb->zfb_ramoff);
                    556:                        nbytes = letoh32(zfb->zfb_size);
                    557:                        lp = (const u_int32_t *)
                    558:                            &cycladesz_firmware[letoh32(zfb->zfb_fileoff)];
                    559:                        for (j = 0; j < nbytes; j += 4, lp++) {
                    560:                                bus_space_write_4(cz->cz_win_st, cz->cz_win_sh,
                    561:                                    ro + j, letoh32(*lp));
                    562:                                delay(10);
                    563:                        }
                    564:                }
                    565:        }
                    566:
                    567:        /* Now restart the MIPS. */
                    568:        CZ_WIN_FPGA(cz);
                    569:        CZ_FPGA_WRITE(cz, FPGA_CPU_START, 0);
                    570:
                    571:        /* Wait for the MIPS to start, then report the results. */
                    572:        CZ_WIN_RAM(cz);
                    573:
                    574: #ifdef CZ_DEBUG
                    575:        printf("%s: waiting for MIPS to start", cz->cz_dev.dv_xname);
                    576: #endif
                    577:        for (i = 0; i < 100; i++) {
                    578:                fid = bus_space_read_4(cz->cz_win_st, cz->cz_win_sh,
                    579:                    ZFIRM_SIG_OFF);
                    580:                if (fid == ZFIRM_SIG) {
                    581:                        /* MIPS has booted. */
                    582:                        break;
                    583:                } else if (fid == ZFIRM_HLT) {
                    584:                        /*
                    585:                         * The MIPS has halted, usually due to a power
                    586:                         * shortage on the expansion module.
                    587:                         */
                    588:                        printf("%s: MIPS halted; possible power supply "
                    589:                            "problem\n", cz->cz_dev.dv_xname);
                    590:                        return (EIO);
                    591:                } else {
                    592: #ifdef CZ_DEBUG
                    593:                        if ((i % 8) == 0)
                    594:                                printf(".");
                    595: #endif
                    596:                        delay(250000);
                    597:                }
                    598:        }
                    599: #ifdef CZ_DEBUG
                    600:        printf("\n");
                    601: #endif
                    602:        if (i == 100) {
                    603:                CZ_WIN_FPGA(cz);
                    604:                printf("%s: MIPS failed to start; wanted 0x%08x got 0x%08x\n",
                    605:                    cz->cz_dev.dv_xname, ZFIRM_SIG, fid);
                    606:                printf("%s: FPGA ID 0x%08x, FPGA version 0x%08x\n",
                    607:                    cz->cz_dev.dv_xname, CZ_FPGA_READ(cz, FPGA_ID),
                    608:                    CZ_FPGA_READ(cz, FPGA_VERSION));
                    609:                return (EIO);
                    610:        }
                    611:
                    612:        /*
                    613:         * Locate the firmware control structures.
                    614:         */
                    615:        cz->cz_fwctl = bus_space_read_4(cz->cz_win_st, cz->cz_win_sh,
                    616:            ZFIRM_CTRLADDR_OFF);
                    617: #ifdef CZ_DEBUG
                    618:        printf("%s: FWCTL structure at offset 0x%08lx\n",
                    619:            cz->cz_dev.dv_xname, cz->cz_fwctl);
                    620: #endif
                    621:
                    622:        CZ_FWCTL_WRITE(cz, BRDCTL_C_OS, C_OS_BSD);
                    623:        CZ_FWCTL_WRITE(cz, BRDCTL_DRVERSION, CZ_DRIVER_VERSION);
                    624:
                    625:        cz->cz_nchannels = CZ_FWCTL_READ(cz, BRDCTL_NCHANNEL);
                    626:
                    627:        switch (cz->cz_mailbox0) {
                    628:        case MAILBOX0_8Zo_V1:
                    629:                board = "Cyclades-8Zo ver. 1";
                    630:                break;
                    631:
                    632:        case MAILBOX0_8Zo_V2:
                    633:                board = "Cyclades-8Zo ver. 2";
                    634:                break;
                    635:
                    636:        case MAILBOX0_Ze_V1:
                    637:                board = "Cyclades-Ze";
                    638:                break;
                    639:
                    640:        default:
                    641:                board = "unknown Cyclades Z-series";
                    642:                break;
                    643:        }
                    644:
                    645:        fid = CZ_FWCTL_READ(cz, BRDCTL_FWVERSION);
                    646:        printf("%s: %s, ", cz->cz_dev.dv_xname, board);
                    647:        if (cz->cz_nchannels == 0)
                    648:                printf("no channels attached, ");
                    649:        else
                    650:                printf("%d channels (ttyCZ%04d..ttyCZ%04d), ",
                    651:                    cz->cz_nchannels, cztty_attached_ttys,
                    652:                    cztty_attached_ttys + (cz->cz_nchannels - 1));
                    653:        printf("firmware %x.%x.%x\n",
                    654:            (fid >> 8) & 0xf, (fid >> 4) & 0xf, fid & 0xf);
                    655:
                    656:        return (0);
                    657: }
                    658:
                    659: /*
                    660:  * cz_poll:
                    661:  *
                    662:  * This card doesn't do interrupts, so scan it for activity every CZ_POLL_MS
                    663:  * ms.
                    664:  */
                    665: void
                    666: cz_poll(void *arg)
                    667: {
                    668:        int s = spltty();
                    669:        struct cz_softc *cz = arg;
                    670:
                    671:        cz_intr(cz);
                    672:        timeout_add(&cz->cz_timeout, cz_timeout_ticks);
                    673:
                    674:        splx(s);
                    675: }
                    676:
                    677: /*
                    678:  * cz_intr:
                    679:  *
                    680:  *     Interrupt service routine.
                    681:  *
                    682:  * We either are receiving an interrupt directly from the board, or we are
                    683:  * in polling mode and it's time to poll.
                    684:  */
                    685: int
                    686: cz_intr(void *arg)
                    687: {
                    688:        int     rval = 0;
                    689:        u_int   command, channel, param;
                    690:        struct  cz_softc *cz = arg;
                    691:        struct  cztty_softc *sc;
                    692:        struct  tty *tp;
                    693:
                    694:        while ((command = (CZ_PLX_READ(cz, PLX_LOCAL_PCI_DOORBELL) & 0xff))) {
                    695:                rval = 1;
                    696:                channel = CZ_FWCTL_READ(cz, BRDCTL_FWCMD_CHANNEL);
                    697:                param = CZ_FWCTL_READ(cz, BRDCTL_FWCMD_PARAM);
                    698:
                    699:                /* now clear this interrupt, posslibly enabling another */
                    700:                CZ_PLX_WRITE(cz, PLX_LOCAL_PCI_DOORBELL, command);
                    701:
                    702:                if (cz->cz_ports == NULL) {
                    703: #ifdef CZ_DEBUG
                    704:                        printf("%s: interrupt on channel %d, but no channels\n",
                    705:                            cz->cz_dev.dv_xname, channel);
                    706: #endif
                    707:                        continue;
                    708:                }
                    709:
                    710:                sc = &cz->cz_ports[channel];
                    711:
                    712:                if (sc->sc_channel == CZTTY_CHANNEL_DEAD)
                    713:                        break;
                    714:
                    715:                tp = sc->sc_tty;
                    716:
                    717:                switch (command) {
                    718:                case C_CM_TXFEMPTY:             /* transmit cases */
                    719:                case C_CM_TXBEMPTY:
                    720:                case C_CM_TXLOWWM:
                    721:                case C_CM_INTBACK:
                    722:                        if (!ISSET(tp->t_state, TS_ISOPEN)) {
                    723: #ifdef CZ_DEBUG
                    724:                                printf("%s: tx intr on closed channel %d\n",
                    725:                                    cz->cz_dev.dv_xname, channel);
                    726: #endif
                    727:                                break;
                    728:                        }
                    729:
                    730:                        if (cztty_transmit(sc, tp)) {
                    731:                                /*
                    732:                                 * Do wakeup stuff here.
                    733:                                 */
                    734:                                ttwakeup(tp);
                    735:                                wakeup(tp);
                    736:                        }
                    737:                        break;
                    738:
                    739:                case C_CM_RXNNDT:               /* receive cases */
                    740:                case C_CM_RXHIWM:
                    741:                case C_CM_INTBACK2:             /* from restart ?? */
                    742: #if 0
                    743:                case C_CM_ICHAR:
                    744: #endif
                    745:                        if (!ISSET(tp->t_state, TS_ISOPEN)) {
                    746:                                CZTTY_BUF_WRITE(sc, BUFCTL_RX_GET,
                    747:                                    CZTTY_BUF_READ(sc, BUFCTL_RX_PUT));
                    748:                                break;
                    749:                        }
                    750:
                    751:                        if (cztty_receive(sc, tp)) {
                    752:                                /*
                    753:                                 * Do wakeup stuff here.
                    754:                                 */
                    755:                                ttwakeup(tp);
                    756:                                wakeup(tp);
                    757:                        }
                    758:                        break;
                    759:
                    760:                case C_CM_MDCD:
                    761:                        if (!ISSET(tp->t_state, TS_ISOPEN))
                    762:                                break;
                    763:
                    764:                        (void) (*linesw[tp->t_line].l_modem)(tp,
                    765:                            ISSET(C_RS_DCD, CZTTY_CHAN_READ(sc,
                    766:                            CHNCTL_RS_STATUS)));
                    767:                        break;
                    768:
                    769:                case C_CM_MDSR:
                    770:                case C_CM_MRI:
                    771:                case C_CM_MCTS:
                    772:                case C_CM_MRTS:
                    773:                        break;
                    774:
                    775:                case C_CM_IOCTLW:
                    776:                        break;
                    777:
                    778:                case C_CM_PR_ERROR:
                    779:                        sc->sc_parity_errors++;
                    780:                        goto error_common;
                    781:
                    782:                case C_CM_FR_ERROR:
                    783:                        sc->sc_framing_errors++;
                    784:                        goto error_common;
                    785:
                    786:                case C_CM_OVR_ERROR:
                    787:                        sc->sc_overflows++;
                    788:  error_common:
                    789:                        if (sc->sc_errors++ == 0)
                    790:                                timeout_add(&sc->sc_diag_to, 60 * hz);
                    791:                        break;
                    792:
                    793:                case C_CM_RXBRK:
                    794:                        if (!ISSET(tp->t_state, TS_ISOPEN))
                    795:                                break;
                    796:
                    797:                        /*
                    798:                         * A break is a \000 character with TTY_FE error
                    799:                         * flags set. So TTY_FE by itself works.
                    800:                         */
                    801:                        (*linesw[tp->t_line].l_rint)(TTY_FE, tp);
                    802:                        ttwakeup(tp);
                    803:                        wakeup(tp);
                    804:                        break;
                    805:
                    806:                default:
                    807: #ifdef CZ_DEBUG
                    808:                        printf("%s: channel %d: Unknown interrupt 0x%x\n",
                    809:                            cz->cz_dev.dv_xname, sc->sc_channel, command);
                    810: #endif
                    811:                        break;
                    812:                }
                    813:        }
                    814:
                    815:        return (rval);
                    816: }
                    817:
                    818: /*
                    819:  * cz_wait_pci_doorbell:
                    820:  *
                    821:  *     Wait for the pci doorbell to be clear - wait for pending
                    822:  *     activity to drain.
                    823:  */
                    824: int
                    825: cz_wait_pci_doorbell(struct cz_softc *cz, char *wstring)
                    826: {
                    827:        int     error;
                    828:
                    829:        while (CZ_PLX_READ(cz, PLX_PCI_LOCAL_DOORBELL)) {
                    830:                error = tsleep(cz, TTIPRI | PCATCH, wstring, max(1, hz/100));
                    831:                if ((error != 0) && (error != EWOULDBLOCK))
                    832:                        return (error);
                    833:        }
                    834:        return (0);
                    835: }
                    836:
                    837: /*****************************************************************************
                    838:  * Cyclades-Z TTY code starts here...
                    839:  *****************************************************************************/
                    840:
                    841: #define CZTTYDIALOUT_MASK      0x80
                    842:
                    843: #define        CZTTY_DIALOUT(dev)      (minor((dev)) & CZTTYDIALOUT_MASK)
                    844: #define        CZTTY_CZ(sc)            ((sc)->sc_parent)
                    845:
                    846: #define        CZTTY_SOFTC(dev)        cztty_getttysoftc(dev)
                    847:
                    848: struct cztty_softc *
                    849: cztty_getttysoftc(dev_t dev)
                    850: {
                    851:        int i, j, k, u = minor(dev) & ~CZTTYDIALOUT_MASK;
                    852:        struct cz_softc *cz;
                    853:
                    854:        for (i = 0, j = 0; i < cz_cd.cd_ndevs; i++) {
                    855:                k = j;
                    856:                cz = (struct cz_softc *)device_lookup(&cz_cd, i);
                    857:                if (cz == NULL)
                    858:                        continue;
                    859:                if (cz->cz_ports == NULL)
                    860:                        continue;
                    861:                j += cz->cz_nchannels;
                    862:                if (j > u)
                    863:                        break;
                    864:        }
                    865:
                    866:        if (i >= cz_cd.cd_ndevs)
                    867:                return (NULL);
                    868:        else
                    869:                return (&cz->cz_ports[u - k]);
                    870: }
                    871:
                    872: int
                    873: cztty_findmajor(void)
                    874: {
                    875:        int     maj;
                    876:
                    877:        for (maj = 0; maj < nchrdev; maj++) {
                    878:                if (cdevsw[maj].d_open == czttyopen)
                    879:                        break;
                    880:        }
                    881:
                    882:        return (maj == nchrdev) ? 0 : maj;
                    883: }
                    884:
                    885: /*
                    886:  * czttytty:
                    887:  *
                    888:  *     Return a pointer to our tty.
                    889:  */
                    890: struct tty *
                    891: czttytty(dev_t dev)
                    892: {
                    893:        struct cztty_softc *sc = CZTTY_SOFTC(dev);
                    894:
                    895: #ifdef DIAGNOSTIC
                    896:        if (sc == NULL)
                    897:                panic("czttytty");
                    898: #endif
                    899:
                    900:        return (sc->sc_tty);
                    901: }
                    902:
                    903: /*
                    904:  * cztty_shutdown:
                    905:  *
                    906:  *     Shut down a port.
                    907:  */
                    908: void
                    909: cztty_shutdown(struct cztty_softc *sc)
                    910: {
                    911:        struct cz_softc *cz = CZTTY_CZ(sc);
                    912:        struct tty *tp = sc->sc_tty;
                    913:        int s;
                    914:
                    915:        s = spltty();
                    916:
                    917:        /* Clear any break condition set with TIOCSBRK. */
                    918:        cztty_break(sc, 0);
                    919:
                    920:        /*
                    921:         * Hang up if necessary.  Wait a bit, so the other side has time to
                    922:         * notice even if we immediately open the port again.
                    923:         */
                    924:        if (ISSET(tp->t_cflag, HUPCL)) {
                    925:                cztty_modem(sc, 0);
                    926:                (void) tsleep(tp, TTIPRI, ttclos, hz);
                    927:        }
                    928:
                    929:        /* Disable the channel. */
                    930:        cz_wait_pci_doorbell(cz, "czdis");
                    931:        CZTTY_CHAN_WRITE(sc, CHNCTL_OP_MODE, C_CH_DISABLE);
                    932:        CZ_FWCTL_WRITE(cz, BRDCTL_HCMD_CHANNEL, sc->sc_channel);
                    933:        CZ_PLX_WRITE(cz, PLX_PCI_LOCAL_DOORBELL, C_CM_IOCTL);
                    934:
                    935:        if ((--cz->cz_nopenchan == 0) && (cz->cz_ih == NULL)) {
                    936: #ifdef CZ_DEBUG
                    937:                printf("%s: Disabling polling\n", cz->cz_dev.dv_xname);
                    938: #endif
                    939:                timeout_del(&cz->cz_timeout);
                    940:        }
                    941:
                    942:        splx(s);
                    943: }
                    944:
                    945: /*
                    946:  * czttyopen:
                    947:  *
                    948:  *     Open a Cyclades-Z serial port.
                    949:  */
                    950: int
                    951: czttyopen(dev_t dev, int flags, int mode, struct proc *p)
                    952: {
                    953:        struct cztty_softc *sc = CZTTY_SOFTC(dev);
                    954:        struct cz_softc *cz;
                    955:        struct tty *tp;
                    956:        int s, error;
                    957:
                    958:        if (sc == NULL)
                    959:                return (ENXIO);
                    960:
                    961:        if (sc->sc_channel == CZTTY_CHANNEL_DEAD)
                    962:                return (ENXIO);
                    963:
                    964:        cz = CZTTY_CZ(sc);
                    965:        tp = sc->sc_tty;
                    966:
                    967:        if (ISSET(tp->t_state, TS_ISOPEN) &&
                    968:            ISSET(tp->t_state, TS_XCLUDE) &&
                    969:            p->p_ucred->cr_uid != 0)
                    970:                return (EBUSY);
                    971:
                    972:        s = spltty();
                    973:
                    974:        /*
                    975:         * Do the following iff this is a first open.
                    976:         */
                    977:        if (!ISSET(tp->t_state, TS_ISOPEN)) {
                    978:                struct termios t;
                    979:
                    980:                tp->t_dev = dev;
                    981:
                    982:                /* If we're turning things on, enable interrupts */
                    983:                if ((cz->cz_nopenchan++ == 0) && (cz->cz_ih == NULL)) {
                    984: #ifdef CZ_DEBUG
                    985:                        printf("%s: Enabling polling.\n",
                    986:                            cz->cz_dev.dv_xname);
                    987: #endif
                    988:                        timeout_add(&cz->cz_timeout, cz_timeout_ticks);
                    989:                }
                    990:
                    991:                /*
                    992:                 * Enable the channel.  Don't actually ring the
                    993:                 * doorbell here; czttyparam() will do it for us.
                    994:                 */
                    995:                cz_wait_pci_doorbell(cz, "czopen");
                    996:
                    997:                CZTTY_CHAN_WRITE(sc, CHNCTL_OP_MODE, C_CH_ENABLE);
                    998:
                    999:                /*
                   1000:                 * Initialize the termios status to the defaults.  Add in the
                   1001:                 * sticky bits from TIOCSFLAGS.
                   1002:                 */
                   1003:                t.c_ispeed = 0;
                   1004:                t.c_ospeed = TTYDEF_SPEED;
                   1005:                t.c_cflag = TTYDEF_CFLAG;
                   1006:                if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL))
                   1007:                        SET(t.c_cflag, CLOCAL);
                   1008:                if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS))
                   1009:                        SET(t.c_cflag, CRTSCTS);
                   1010:
                   1011:                /*
                   1012:                 * Reset the input and output rings.  Do this before
                   1013:                 * we call czttyparam(), as that function enables
                   1014:                 * the channel.
                   1015:                 */
                   1016:                CZTTY_BUF_WRITE(sc, BUFCTL_RX_GET,
                   1017:                    CZTTY_BUF_READ(sc, BUFCTL_RX_PUT));
                   1018:                CZTTY_BUF_WRITE(sc, BUFCTL_TX_PUT,
                   1019:                    CZTTY_BUF_READ(sc, BUFCTL_TX_GET));
                   1020:
                   1021:                /* Make sure czttyparam() will see changes. */
                   1022:                tp->t_ospeed = 0;
                   1023:                (void) czttyparam(tp, &t);
                   1024:                tp->t_iflag = TTYDEF_IFLAG;
                   1025:                tp->t_oflag = TTYDEF_OFLAG;
                   1026:                tp->t_lflag = TTYDEF_LFLAG;
                   1027:                ttychars(tp);
                   1028:                ttsetwater(tp);
                   1029:
                   1030:                /*
                   1031:                 * Turn on DTR.  We must always do this, even if carrier is not
                   1032:                 * present, because otherwise we'd have to use TIOCSDTR
                   1033:                 * immediately after setting CLOCAL, which applications do not
                   1034:                 * expect.  We always assert DTR while the device is open
                   1035:                 * unless explicitly requested to deassert it.
                   1036:                 */
                   1037:                cztty_modem(sc, 1);
                   1038:        }
                   1039:
                   1040:        splx(s);
                   1041:
                   1042:        error = ttyopen(CZTTY_DIALOUT(dev), tp);
                   1043:        if (error)
                   1044:                goto bad;
                   1045:
                   1046:        error = (*linesw[tp->t_line].l_open)(dev, tp);
                   1047:        if (error)
                   1048:                goto bad;
                   1049:
                   1050:        return (0);
                   1051:
                   1052:  bad:
                   1053:        if (!ISSET(tp->t_state, TS_ISOPEN)) {
                   1054:                /*
                   1055:                 * We failed to open the device, and nobody else had it opened.
                   1056:                 * Clean up the state as appropriate.
                   1057:                 */
                   1058:                cztty_shutdown(sc);
                   1059:        }
                   1060:
                   1061:        return (error);
                   1062: }
                   1063:
                   1064: /*
                   1065:  * czttyclose:
                   1066:  *
                   1067:  *     Close a Cyclades-Z serial port.
                   1068:  */
                   1069: int
                   1070: czttyclose(dev_t dev, int flags, int mode, struct proc *p)
                   1071: {
                   1072:        struct cztty_softc *sc = CZTTY_SOFTC(dev);
                   1073:        struct tty *tp = sc->sc_tty;
                   1074:
                   1075:        /* XXX This is for cons.c. */
                   1076:        if (!ISSET(tp->t_state, TS_ISOPEN))
                   1077:                return (0);
                   1078:
                   1079:        (*linesw[tp->t_line].l_close)(tp, flags);
                   1080:        ttyclose(tp);
                   1081:
                   1082:        if (!ISSET(tp->t_state, TS_ISOPEN)) {
                   1083:                /*
                   1084:                 * Although we got a last close, the device may still be in
                   1085:                 * use; e.g. if this was the dialout node, and there are still
                   1086:                 * processes waiting for carrier on the non-dialout node.
                   1087:                 */
                   1088:                cztty_shutdown(sc);
                   1089:        }
                   1090:
                   1091:        return (0);
                   1092: }
                   1093:
                   1094: /*
                   1095:  * czttyread:
                   1096:  *
                   1097:  *     Read from a Cyclades-Z serial port.
                   1098:  */
                   1099: int
                   1100: czttyread(dev_t dev, struct uio *uio, int flags)
                   1101: {
                   1102:        struct cztty_softc *sc = CZTTY_SOFTC(dev);
                   1103:        struct tty *tp = sc->sc_tty;
                   1104:
                   1105:        return ((*linesw[tp->t_line].l_read)(tp, uio, flags));
                   1106: }
                   1107:
                   1108: /*
                   1109:  * czttywrite:
                   1110:  *
                   1111:  *     Write to a Cyclades-Z serial port.
                   1112:  */
                   1113: int
                   1114: czttywrite(dev_t dev, struct uio *uio, int flags)
                   1115: {
                   1116:        struct cztty_softc *sc = CZTTY_SOFTC(dev);
                   1117:        struct tty *tp = sc->sc_tty;
                   1118:
                   1119:        return ((*linesw[tp->t_line].l_write)(tp, uio, flags));
                   1120: }
                   1121:
                   1122: #if 0
                   1123: /*
                   1124:  * czttypoll:
                   1125:  *
                   1126:  *     Poll a Cyclades-Z serial port.
                   1127:  */
                   1128: int
                   1129: czttypoll(dev_t dev, int events, struct proc p)
                   1130: {
                   1131:        struct cztty_softc *sc = CZTTY_SOFTC(dev);
                   1132:        struct tty *tp = sc->sc_tty;
                   1133:
                   1134:        return ((*linesw[tp->t_line].l_poll)(tp, events, p));
                   1135: }
                   1136: #endif
                   1137:
                   1138: /*
                   1139:  * czttyioctl:
                   1140:  *
                   1141:  *     Perform a control operation on a Cyclades-Z serial port.
                   1142:  */
                   1143: int
                   1144: czttyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
                   1145: {
                   1146:        struct cztty_softc *sc = CZTTY_SOFTC(dev);
                   1147:        struct tty *tp = sc->sc_tty;
                   1148:        int s, error;
                   1149:
                   1150:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
                   1151:        if (error >= 0)
                   1152:                return (error);
                   1153:
                   1154:        error = ttioctl(tp, cmd, data, flag, p);
                   1155:        if (error >= 0)
                   1156:                return (error);
                   1157:
                   1158:        error = 0;
                   1159:
                   1160:        s = spltty();
                   1161:
                   1162:        switch (cmd) {
                   1163:        case TIOCSBRK:
                   1164:                cztty_break(sc, 1);
                   1165:                break;
                   1166:
                   1167:        case TIOCCBRK:
                   1168:                cztty_break(sc, 0);
                   1169:                break;
                   1170:
                   1171:        case TIOCGFLAGS:
                   1172:                *(int *)data = sc->sc_swflags;
                   1173:                break;
                   1174:
                   1175:        case TIOCSFLAGS:
                   1176:                error = suser(p, 0);
                   1177:                if (error)
                   1178:                        break;
                   1179:                sc->sc_swflags = *(int *)data;
                   1180:                break;
                   1181:
                   1182:        case TIOCSDTR:
                   1183:                cztty_modem(sc, 1);
                   1184:                break;
                   1185:
                   1186:        case TIOCCDTR:
                   1187:                cztty_modem(sc, 0);
                   1188:                break;
                   1189:
                   1190:        case TIOCMSET:
                   1191:        case TIOCMBIS:
                   1192:        case TIOCMBIC:
                   1193:                tiocm_to_cztty(sc, cmd, *(int *)data);
                   1194:                break;
                   1195:
                   1196:        case TIOCMGET:
                   1197:                *(int *)data = cztty_to_tiocm(sc);
                   1198:                break;
                   1199:
                   1200:        default:
                   1201:                error = ENOTTY;
                   1202:                break;
                   1203:        }
                   1204:
                   1205:        splx(s);
                   1206:
                   1207:        return (error);
                   1208: }
                   1209:
                   1210: /*
                   1211:  * cztty_break:
                   1212:  *
                   1213:  *     Set or clear BREAK on a port.
                   1214:  */
                   1215: void
                   1216: cztty_break(struct cztty_softc *sc, int onoff)
                   1217: {
                   1218:        struct cz_softc *cz = CZTTY_CZ(sc);
                   1219:
                   1220:        cz_wait_pci_doorbell(cz, "czbreak");
                   1221:
                   1222:        CZ_FWCTL_WRITE(cz, BRDCTL_HCMD_CHANNEL, sc->sc_channel);
                   1223:        CZ_PLX_WRITE(cz, PLX_PCI_LOCAL_DOORBELL,
                   1224:            onoff ? C_CM_SET_BREAK : C_CM_CLR_BREAK);
                   1225: }
                   1226:
                   1227: /*
                   1228:  * cztty_modem:
                   1229:  *
                   1230:  *     Set or clear DTR on a port.
                   1231:  */
                   1232: void
                   1233: cztty_modem(struct cztty_softc *sc, int onoff)
                   1234: {
                   1235:        struct cz_softc *cz = CZTTY_CZ(sc);
                   1236:
                   1237:        if (sc->sc_rs_control_dtr == 0)
                   1238:                return;
                   1239:
                   1240:        cz_wait_pci_doorbell(cz, "czmod");
                   1241:
                   1242:        if (onoff)
                   1243:                sc->sc_chanctl_rs_control |= sc->sc_rs_control_dtr;
                   1244:        else
                   1245:                sc->sc_chanctl_rs_control &= ~sc->sc_rs_control_dtr;
                   1246:        CZTTY_CHAN_WRITE(sc, CHNCTL_RS_CONTROL, sc->sc_chanctl_rs_control);
                   1247:
                   1248:        CZ_FWCTL_WRITE(cz, BRDCTL_HCMD_CHANNEL, sc->sc_channel);
                   1249:        CZ_PLX_WRITE(cz, PLX_PCI_LOCAL_DOORBELL, C_CM_IOCTLM);
                   1250: }
                   1251:
                   1252: /*
                   1253:  * tiocm_to_cztty:
                   1254:  *
                   1255:  *     Process TIOCM* ioctls.
                   1256:  */
                   1257: void
                   1258: tiocm_to_cztty(struct cztty_softc *sc, u_long how, int ttybits)
                   1259: {
                   1260:        struct cz_softc *cz = CZTTY_CZ(sc);
                   1261:        u_int32_t czttybits;
                   1262:
                   1263:        czttybits = 0;
                   1264:        if (ISSET(ttybits, TIOCM_DTR))
                   1265:                SET(czttybits, C_RS_DTR);
                   1266:        if (ISSET(ttybits, TIOCM_RTS))
                   1267:                SET(czttybits, C_RS_RTS);
                   1268:
                   1269:        cz_wait_pci_doorbell(cz, "cztiocm");
                   1270:
                   1271:        switch (how) {
                   1272:        case TIOCMBIC:
                   1273:                CLR(sc->sc_chanctl_rs_control, czttybits);
                   1274:                break;
                   1275:
                   1276:        case TIOCMBIS:
                   1277:                SET(sc->sc_chanctl_rs_control, czttybits);
                   1278:                break;
                   1279:
                   1280:        case TIOCMSET:
                   1281:                CLR(sc->sc_chanctl_rs_control, C_RS_DTR | C_RS_RTS);
                   1282:                SET(sc->sc_chanctl_rs_control, czttybits);
                   1283:                break;
                   1284:        }
                   1285:
                   1286:        CZTTY_CHAN_WRITE(sc, CHNCTL_RS_CONTROL, sc->sc_chanctl_rs_control);
                   1287:
                   1288:        CZ_FWCTL_WRITE(cz, BRDCTL_HCMD_CHANNEL, sc->sc_channel);
                   1289:        CZ_PLX_WRITE(cz, PLX_PCI_LOCAL_DOORBELL, C_CM_IOCTLM);
                   1290: }
                   1291:
                   1292: /*
                   1293:  * cztty_to_tiocm:
                   1294:  *
                   1295:  *     Process the TIOCMGET ioctl.
                   1296:  */
                   1297: int
                   1298: cztty_to_tiocm(struct cztty_softc *sc)
                   1299: {
                   1300:        struct cz_softc *cz = CZTTY_CZ(sc);
                   1301:        u_int32_t rs_status, op_mode;
                   1302:        int ttybits = 0;
                   1303:
                   1304:        cz_wait_pci_doorbell(cz, "cztty");
                   1305:
                   1306:        rs_status = CZTTY_CHAN_READ(sc, CHNCTL_RS_STATUS);
                   1307:        op_mode = CZTTY_CHAN_READ(sc, CHNCTL_OP_MODE);
                   1308:
                   1309:        if (ISSET(rs_status, C_RS_RTS))
                   1310:                SET(ttybits, TIOCM_RTS);
                   1311:        if (ISSET(rs_status, C_RS_CTS))
                   1312:                SET(ttybits, TIOCM_CTS);
                   1313:        if (ISSET(rs_status, C_RS_DCD))
                   1314:                SET(ttybits, TIOCM_CAR);
                   1315:        if (ISSET(rs_status, C_RS_DTR))
                   1316:                SET(ttybits, TIOCM_DTR);
                   1317:        if (ISSET(rs_status, C_RS_RI))
                   1318:                SET(ttybits, TIOCM_RNG);
                   1319:        if (ISSET(rs_status, C_RS_DSR))
                   1320:                SET(ttybits, TIOCM_DSR);
                   1321:
                   1322:        if (ISSET(op_mode, C_CH_ENABLE))
                   1323:                SET(ttybits, TIOCM_LE);
                   1324:
                   1325:        return (ttybits);
                   1326: }
                   1327:
                   1328: /*
                   1329:  * czttyparam:
                   1330:  *
                   1331:  *     Set Cyclades-Z serial port parameters from termios.
                   1332:  *
                   1333:  *     XXX Should just copy the whole termios after making
                   1334:  *     XXX sure all the changes could be done.
                   1335:  */
                   1336: int
                   1337: czttyparam(struct tty *tp, struct termios *t)
                   1338: {
                   1339:        struct cztty_softc *sc = CZTTY_SOFTC(tp->t_dev);
                   1340:        struct cz_softc *cz = CZTTY_CZ(sc);
                   1341:        u_int32_t rs_status;
                   1342:        int ospeed, cflag;
                   1343:
                   1344:        ospeed = t->c_ospeed;
                   1345:        cflag = t->c_cflag;
                   1346:
                   1347:        /* Check requested parameters. */
                   1348:        if (ospeed < 0)
                   1349:                return (EINVAL);
                   1350:        if (t->c_ispeed && t->c_ispeed != ospeed)
                   1351:                return (EINVAL);
                   1352:
                   1353:        if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR)) {
                   1354:                SET(cflag, CLOCAL);
                   1355:                CLR(cflag, HUPCL);
                   1356:        }
                   1357:
                   1358:        /*
                   1359:         * If there were no changes, don't do anything.  This avoids dropping
                   1360:         * input and improves performance when all we did was frob things like
                   1361:         * VMIN and VTIME.
                   1362:         */
                   1363:        if (tp->t_ospeed == ospeed &&
                   1364:            tp->t_cflag == cflag)
                   1365:                return (0);
                   1366:
                   1367:        /* Data bits. */
                   1368:        sc->sc_chanctl_comm_data_l = 0;
                   1369:        switch (t->c_cflag & CSIZE) {
                   1370:        case CS5:
                   1371:                sc->sc_chanctl_comm_data_l |= C_DL_CS5;
                   1372:                break;
                   1373:
                   1374:        case CS6:
                   1375:                sc->sc_chanctl_comm_data_l |= C_DL_CS6;
                   1376:                break;
                   1377:
                   1378:        case CS7:
                   1379:                sc->sc_chanctl_comm_data_l |= C_DL_CS7;
                   1380:                break;
                   1381:
                   1382:        case CS8:
                   1383:                sc->sc_chanctl_comm_data_l |= C_DL_CS8;
                   1384:                break;
                   1385:        }
                   1386:
                   1387:        /* Stop bits. */
                   1388:        if (t->c_cflag & CSTOPB) {
                   1389:                if ((sc->sc_chanctl_comm_data_l & C_DL_CS) == C_DL_CS5)
                   1390:                        sc->sc_chanctl_comm_data_l |= C_DL_15STOP;
                   1391:                else
                   1392:                        sc->sc_chanctl_comm_data_l |= C_DL_2STOP;
                   1393:        } else
                   1394:                sc->sc_chanctl_comm_data_l |= C_DL_1STOP;
                   1395:
                   1396:        /* Parity. */
                   1397:        if (t->c_cflag & PARENB) {
                   1398:                if (t->c_cflag & PARODD)
                   1399:                        sc->sc_chanctl_comm_parity = C_PR_ODD;
                   1400:                else
                   1401:                        sc->sc_chanctl_comm_parity = C_PR_EVEN;
                   1402:        } else
                   1403:                sc->sc_chanctl_comm_parity = C_PR_NONE;
                   1404:
                   1405:        /*
                   1406:         * Initialize flow control pins depending on the current flow control
                   1407:         * mode.
                   1408:         */
                   1409:        if (ISSET(t->c_cflag, CRTSCTS)) {
                   1410:                sc->sc_rs_control_dtr = C_RS_DTR;
                   1411:                sc->sc_chanctl_hw_flow = C_RS_CTS | C_RS_RTS;
                   1412:        } else if (ISSET(t->c_cflag, MDMBUF)) {
                   1413:                sc->sc_rs_control_dtr = 0;
                   1414:                sc->sc_chanctl_hw_flow = C_RS_DCD | C_RS_DTR;
                   1415:        } else {
                   1416:                /*
                   1417:                 * If no flow control, then always set RTS.  This will make
                   1418:                 * the other side happy if it mistakenly thinks we're doing
                   1419:                 * RTS/CTS flow control.
                   1420:                 */
                   1421:                sc->sc_rs_control_dtr = C_RS_DTR | C_RS_RTS;
                   1422:                sc->sc_chanctl_hw_flow = 0;
                   1423:                if (ISSET(sc->sc_chanctl_rs_control, C_RS_DTR))
                   1424:                        SET(sc->sc_chanctl_rs_control, C_RS_RTS);
                   1425:                else
                   1426:                        CLR(sc->sc_chanctl_rs_control, C_RS_RTS);
                   1427:        }
                   1428:
                   1429:        /* Baud rate. */
                   1430:        sc->sc_chanctl_comm_baud = ospeed;
                   1431:
                   1432:        /* Copy to tty. */
                   1433:        tp->t_ispeed =  0;
                   1434:        tp->t_ospeed = t->c_ospeed;
                   1435:        tp->t_cflag = t->c_cflag;
                   1436:
                   1437:        /*
                   1438:         * Now load the channel control structure.
                   1439:         */
                   1440:
                   1441:        cz_wait_pci_doorbell(cz, "czparam");
                   1442:
                   1443:        CZTTY_CHAN_WRITE(sc, CHNCTL_COMM_BAUD, sc->sc_chanctl_comm_baud);
                   1444:        CZTTY_CHAN_WRITE(sc, CHNCTL_COMM_DATA_L, sc->sc_chanctl_comm_data_l);
                   1445:        CZTTY_CHAN_WRITE(sc, CHNCTL_COMM_PARITY, sc->sc_chanctl_comm_parity);
                   1446:        CZTTY_CHAN_WRITE(sc, CHNCTL_HW_FLOW, sc->sc_chanctl_hw_flow);
                   1447:        CZTTY_CHAN_WRITE(sc, CHNCTL_RS_CONTROL, sc->sc_chanctl_rs_control);
                   1448:
                   1449:        CZ_FWCTL_WRITE(cz, BRDCTL_HCMD_CHANNEL, sc->sc_channel);
                   1450:        CZ_PLX_WRITE(cz, PLX_PCI_LOCAL_DOORBELL, C_CM_IOCTLW);
                   1451:
                   1452:        cz_wait_pci_doorbell(cz, "czparam");
                   1453:
                   1454:        CZ_FWCTL_WRITE(cz, BRDCTL_HCMD_CHANNEL, sc->sc_channel);
                   1455:        CZ_PLX_WRITE(cz, PLX_PCI_LOCAL_DOORBELL, C_CM_IOCTLM);
                   1456:
                   1457:        cz_wait_pci_doorbell(cz, "czparam");
                   1458:
                   1459:        /*
                   1460:         * Update the tty layer's idea of the carrier bit, in case we changed
                   1461:         * CLOCAL.  We don't hang up here; we only do that by explicit
                   1462:         * request.
                   1463:         */
                   1464:        rs_status = CZTTY_CHAN_READ(sc, CHNCTL_RS_STATUS);
                   1465:        (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(rs_status, C_RS_DCD));
                   1466:
                   1467:        return (0);
                   1468: }
                   1469:
                   1470: /*
                   1471:  * czttystart:
                   1472:  *
                   1473:  *     Start or restart transmission.
                   1474:  */
                   1475: void
                   1476: czttystart(struct tty *tp)
                   1477: {
                   1478:        struct cztty_softc *sc = CZTTY_SOFTC(tp->t_dev);
                   1479:        int s;
                   1480:
                   1481:        s = spltty();
                   1482:        if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
                   1483:                goto out;
                   1484:
                   1485:        if (tp->t_outq.c_cc <= tp->t_lowat) {
                   1486:                if (ISSET(tp->t_state, TS_ASLEEP)) {
                   1487:                        CLR(tp->t_state, TS_ASLEEP);
                   1488:                        wakeup(&tp->t_outq);
                   1489:                }
                   1490:                selwakeup(&tp->t_wsel);
                   1491:                if (tp->t_outq.c_cc == 0)
                   1492:                        goto out;
                   1493:        }
                   1494:
                   1495:        cztty_transmit(sc, tp);
                   1496:  out:
                   1497:        splx(s);
                   1498: }
                   1499:
                   1500: /*
                   1501:  * czttystop:
                   1502:  *
                   1503:  *     Stop output, e.g., for ^S or output flush.
                   1504:  */
                   1505: int
                   1506: czttystop(struct tty *tp, int flag)
                   1507: {
                   1508:
                   1509:        /*
                   1510:         * XXX We don't do anything here, yet.  Mostly, I don't know
                   1511:         * XXX exactly how this should be implemented on this device.
                   1512:         * XXX We've given a big chunk of data to the MIPS already,
                   1513:         * XXX and I don't know how we request the MIPS to stop sending
                   1514:         * XXX the data.  So, punt for now.  --thorpej
                   1515:         */
                   1516:        return (0);
                   1517: }
                   1518:
                   1519: /*
                   1520:  * cztty_diag:
                   1521:  *
                   1522:  *     Issue a scheduled diagnostic message.
                   1523:  */
                   1524: void
                   1525: cztty_diag(void *arg)
                   1526: {
                   1527:        struct cztty_softc *sc = arg;
                   1528:        struct cz_softc *cz = CZTTY_CZ(sc);
                   1529:        u_int overflows, parity_errors, framing_errors;
                   1530:        int s;
                   1531:
                   1532:        s = spltty();
                   1533:
                   1534:        overflows = sc->sc_overflows;
                   1535:        sc->sc_overflows = 0;
                   1536:
                   1537:        parity_errors = sc->sc_parity_errors;
                   1538:        sc->sc_parity_errors = 0;
                   1539:
                   1540:        framing_errors = sc->sc_framing_errors;
                   1541:        sc->sc_framing_errors = 0;
                   1542:
                   1543:        sc->sc_errors = 0;
                   1544:
                   1545:        splx(s);
                   1546:
                   1547:        log(LOG_WARNING,
                   1548:            "%s: channel %d: %u overflow%s, %u parity, %u framing error%s\n",
                   1549:            cz->cz_dev.dv_xname, sc->sc_channel,
                   1550:            overflows, overflows == 1 ? "" : "s",
                   1551:            parity_errors,
                   1552:            framing_errors, framing_errors == 1 ? "" : "s");
                   1553: }
                   1554:
                   1555: /*
                   1556:  * tx and rx ring buffer size macros:
                   1557:  *
                   1558:  * The transmitter and receiver both use ring buffers. For each one, there
                   1559:  * is a get (consumer) and a put (producer) offset. The get value is the
                   1560:  * next byte to be read from the ring, and the put is the next one to be
                   1561:  * put into the ring.  get == put means the ring is empty.
                   1562:  *
                   1563:  * For each ring, the firmware controls one of (get, put) and this driver
                   1564:  * controls the other. For transmission, this driver updates put to point
                   1565:  * past the valid data, and the firmware moves get as bytes are sent. Likewise
                   1566:  * for receive, the driver controls put, and this driver controls get.
                   1567:  */
                   1568: #define        TX_MOVEABLE(g, p, s)    (((g) > (p)) ? ((g) - (p) - 1) : ((s) - (p)))
                   1569: #define RX_MOVEABLE(g, p, s)   (((g) > (p)) ? ((s) - (g)) : ((p) - (g)))
                   1570:
                   1571: /*
                   1572:  * cztty_transmit()
                   1573:  *
                   1574:  * Look at the tty for this port and start sending.
                   1575:  */
                   1576: int
                   1577: cztty_transmit(struct cztty_softc *sc, struct tty *tp)
                   1578: {
                   1579:        struct cz_softc *cz = CZTTY_CZ(sc);
                   1580:        u_int move, get, put, size, address;
                   1581: #ifdef HOSTRAMCODE
                   1582:        int error, done = 0;
                   1583: #else
                   1584:        int done = 0;
                   1585: #endif
                   1586:
                   1587:        size    = CZTTY_BUF_READ(sc, BUFCTL_TX_BUFSIZE);
                   1588:        get     = CZTTY_BUF_READ(sc, BUFCTL_TX_GET);
                   1589:        put     = CZTTY_BUF_READ(sc, BUFCTL_TX_PUT);
                   1590:        address = CZTTY_BUF_READ(sc, BUFCTL_TX_BUFADDR);
                   1591:
                   1592:        while ((tp->t_outq.c_cc > 0) && ((move = TX_MOVEABLE(get, put, size)))){
                   1593: #ifdef HOSTRAMCODE
                   1594:                if (0) {
                   1595:                        move = min(tp->t_outq.c_cc, move);
                   1596:                        error = q_to_b(&tp->t_outq, 0, move);
                   1597:                        if (error != move) {
                   1598:                                printf("%s: channel %d: error moving to "
                   1599:                                    "transmit buf\n", cz->cz_dev.dv_xname,
                   1600:                                    sc->sc_channel);
                   1601:                                move = error;
                   1602:                        }
                   1603:                } else {
                   1604: #endif
                   1605:                        move = min(ndqb(&tp->t_outq, 0), move);
                   1606:                        bus_space_write_region_1(cz->cz_win_st, cz->cz_win_sh,
                   1607:                            address + put, tp->t_outq.c_cf, move);
                   1608:                        ndflush(&tp->t_outq, move);
                   1609: #ifdef HOSTRAMCODE
                   1610:                }
                   1611: #endif
                   1612:
                   1613:                put = ((put + move) % size);
                   1614:                done = 1;
                   1615:        }
                   1616:        if (done) {
                   1617:                CZTTY_BUF_WRITE(sc, BUFCTL_TX_PUT, put);
                   1618:        }
                   1619:        return (done);
                   1620: }
                   1621:
                   1622: int
                   1623: cztty_receive(struct cztty_softc *sc, struct tty *tp)
                   1624: {
                   1625:        struct cz_softc *cz = CZTTY_CZ(sc);
                   1626:        u_int get, put, size, address;
                   1627:        int done = 0, ch;
                   1628:
                   1629:        size    = CZTTY_BUF_READ(sc, BUFCTL_RX_BUFSIZE);
                   1630:        get     = CZTTY_BUF_READ(sc, BUFCTL_RX_GET);
                   1631:        put     = CZTTY_BUF_READ(sc, BUFCTL_RX_PUT);
                   1632:        address = CZTTY_BUF_READ(sc, BUFCTL_RX_BUFADDR);
                   1633:
                   1634:        while ((get != put) && ((tp->t_canq.c_cc + tp->t_rawq.c_cc) < tp->t_hiwat)) {
                   1635: #ifdef HOSTRAMCODE
                   1636:                if (hostram)
                   1637:                        ch = ((char *)fifoaddr)[get];
                   1638:                } else {
                   1639: #endif
                   1640:                        ch = bus_space_read_1(cz->cz_win_st, cz->cz_win_sh,
                   1641:                            address + get);
                   1642: #ifdef HOSTRAMCODE
                   1643:                }
                   1644: #endif
                   1645:                (*linesw[tp->t_line].l_rint)(ch, tp);
                   1646:                get = (get + 1) % size;
                   1647:                done = 1;
                   1648:        }
                   1649:        if (done) {
                   1650:                CZTTY_BUF_WRITE(sc, BUFCTL_RX_GET, get);
                   1651:        }
                   1652:        return (done);
                   1653: }

CVSweb