root/dev/ic/cy.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cy_probe_common
  2. cy_attach
  3. cyopen
  4. cyclose
  5. cyread
  6. cywrite
  7. cytty
  8. cyioctl
  9. cystart
  10. cystop
  11. cyparam
  12. cy_modem_control
  13. cy_poll
  14. cy_intr
  15. cy_enable_transmitter
  16. cd1400_channel_cmd
  17. cy_speed

    1 /*      $OpenBSD: cy.c,v 1.25 2005/11/21 18:16:39 millert Exp $ */
    2 /*
    3  * Copyright (c) 1996 Timo Rossi.
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. Neither the name of the author nor the names of contributors
   15  *    may be used to endorse or promote products derived from this software
   16  *    without specific prior written permission.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  */
   30 
   31 /*
   32  * cy.c
   33  *
   34  * Driver for Cyclades Cyclom-8/16/32 multiport serial cards
   35  * (currently not tested with Cyclom-32 cards)
   36  *
   37  * Timo Rossi, 1996
   38  *
   39  * Supports both ISA and PCI Cyclom cards
   40  *
   41  * Uses CD1400 automatic CTS flow control, and
   42  * if CY_HW_RTS is defined, uses CD1400 automatic input flow control.
   43  * This requires a special cable that exchanges the RTS and DTR lines.
   44  *
   45  * Lots of debug output can be enabled by defining CY_DEBUG
   46  * Some debugging counters (number of receive/transmit interrupts etc.)
   47  * can be enabled by defining CY_DEBUG1
   48  *
   49  * This version uses the bus_space/io_??() stuff
   50  *
   51  */
   52 
   53 /* NCY is the number of Cyclom cards in the machine */
   54 #include "cy.h"
   55 #if NCY > 0
   56 
   57 #include <sys/types.h>
   58 #include <sys/param.h>
   59 #include <sys/ioctl.h>
   60 #include <sys/syslog.h>
   61 #include <sys/fcntl.h>
   62 #include <sys/tty.h>
   63 #include <sys/proc.h>
   64 #include <sys/conf.h>
   65 #include <sys/user.h>
   66 #include <sys/selinfo.h>
   67 #include <sys/device.h>
   68 #include <sys/malloc.h>
   69 #include <sys/systm.h>
   70 
   71 #include <machine/bus.h>
   72 #include <machine/intr.h>
   73 
   74 #if NCY_ISA > 0 
   75 #include <dev/isa/isavar.h>
   76 #include <dev/isa/isareg.h>
   77 #endif /* NCY_ISA > 0 */
   78 #if NCY_PCI > 0
   79 #include <dev/pci/pcivar.h>
   80 #include <dev/pci/pcireg.h>
   81 #include <dev/pci/pcidevs.h>
   82 #endif /* NCY_PCI > 0 */
   83 
   84 #include <dev/ic/cd1400reg.h>
   85 #include <dev/ic/cyreg.h>
   86 
   87 
   88 int     cy_intr(void *);
   89 int     cyparam(struct tty *, struct termios *);
   90 void    cystart(struct tty *);
   91 void    cy_poll(void *);
   92 int     cy_modem_control(struct cy_port *, int, int);
   93 void    cy_enable_transmitter(struct cy_port *);
   94 void    cd1400_channel_cmd(struct cy_port *, int);
   95 int     cy_speed(speed_t, int *, int *, int);
   96 
   97 struct cfdriver cy_cd = {
   98         NULL, "cy", DV_TTY
   99 };
  100 
  101 /*
  102  * Common probe routine
  103  *
  104  * returns the number of chips found.
  105  */
  106 int
  107 cy_probe_common(bus_space_tag_t memt, bus_space_handle_t memh, int bustype)
  108 {
  109         int cy_chip, chip_offs;
  110         u_char firmware_ver;
  111         int nchips;
  112 
  113         /* Cyclom card hardware reset */
  114         bus_space_write_1(memt, memh, CY16_RESET<<bustype, 0);
  115         DELAY(500); /* wait for reset to complete */
  116         bus_space_write_1(memt, memh, CY_CLEAR_INTR<<bustype, 0);
  117 
  118 #ifdef CY_DEBUG
  119         printf("cy: card reset done\n");
  120 #endif
  121 
  122         nchips = 0;
  123 
  124         for (cy_chip = 0, chip_offs = 0;
  125             cy_chip < CY_MAX_CD1400s;
  126             cy_chip++, chip_offs += (CY_CD1400_MEMSPACING << bustype)) {
  127                 int i;
  128 
  129                 /* the last 4 cd1400s are 'interleaved'
  130                    with the first 4 on 32-port boards */
  131                 if (cy_chip == 4)
  132                         chip_offs -= (CY32_ADDR_FIX << bustype);
  133 
  134 #ifdef CY_DEBUG
  135                 printf("cy: probe chip %d offset 0x%lx ... ",
  136                     cy_chip, chip_offs);
  137 #endif
  138 
  139                 /* wait until the chip is ready for command */
  140                 DELAY(1000);
  141                 if (bus_space_read_1(memt, memh, chip_offs +
  142                     ((CD1400_CCR << 1) << bustype)) != 0) {
  143 #ifdef CY_DEBUG
  144                         printf("not ready for command\n");
  145 #endif
  146                         break;
  147                 }
  148 
  149                 /* clear the firmware version reg. */
  150                 bus_space_write_1(memt, memh, chip_offs +
  151                     ((CD1400_GFRCR << 1) << bustype), 0);
  152 
  153                 /*
  154                  * On Cyclom-16 references to non-existent chip 4
  155                  * actually access chip 0 (address line 9 not decoded).
  156                  * Here we check if the clearing of chip 4 GFRCR actually
  157                  * cleared chip 0 GFRCR. In that case we have a 16 port card.
  158                  */
  159                 if (cy_chip == 4 &&
  160                     bus_space_read_1(memt, memh, chip_offs +
  161                         ((CD1400_GFRCR << 1) << bustype)) == 0)
  162                         break;
  163 
  164                 /* reset the chip */
  165                 bus_space_write_1(memt, memh, chip_offs +
  166                     ((CD1400_CCR << 1) << bustype),
  167                     CD1400_CCR_CMDRESET | CD1400_CCR_FULLRESET);
  168 
  169                 /* wait for the chip to initialize itself */
  170                 for (i = 0; i < 200; i++) {
  171                         DELAY(50);
  172                         firmware_ver = bus_space_read_1(memt, memh, chip_offs +
  173                             ((CD1400_GFRCR << 1) << bustype));
  174                         if ((firmware_ver & 0xf0) == 0x40) /* found a CD1400 */
  175                                 break;
  176                 }
  177 #ifdef CY_DEBUG
  178                 printf("firmware version 0x%x\n", firmware_ver);
  179 #endif      
  180 
  181                 if ((firmware_ver & 0xf0) != 0x40)
  182                         break;
  183 
  184                 /* firmware version OK, CD1400 found */
  185                 nchips++;
  186         }
  187 
  188         if (nchips == 0) {
  189 #ifdef CY_DEBUG
  190                 printf("no CD1400s found\n");
  191 #endif
  192                 return (0);
  193         }
  194 
  195 #ifdef CY_DEBUG
  196         printf("found %d CD1400s\n", nchips);
  197 #endif
  198 
  199         return (nchips);
  200 }
  201 
  202 void
  203 cy_attach(parent, self)
  204         struct device *parent, *self;
  205 {
  206         int card, port, cy_chip, num_chips, cdu, chip_offs, cy_clock;
  207         struct cy_softc *sc = (void *)self;
  208 
  209         card = sc->sc_dev.dv_unit;
  210         num_chips = sc->sc_nr_cd1400s;
  211         if (num_chips == 0)
  212                 return;
  213 
  214         timeout_set(&sc->sc_poll_to, cy_poll, sc);
  215         bzero(sc->sc_ports, sizeof(sc->sc_ports));
  216         sc->sc_nports = num_chips * CD1400_NO_OF_CHANNELS;
  217 
  218         port = 0;
  219         for (cy_chip = 0, chip_offs = 0;
  220             cy_chip < num_chips;
  221             cy_chip++, chip_offs += (CY_CD1400_MEMSPACING<<sc->sc_bustype)) {
  222                 if (cy_chip == 4)
  223                         chip_offs -= (CY32_ADDR_FIX<<sc->sc_bustype);
  224 
  225 #ifdef CY_DEBUG
  226                 printf("attach CD1400 #%d offset 0x%x\n", cy_chip, chip_offs);
  227 #endif
  228                 sc->sc_cd1400_offs[cy_chip] = chip_offs;
  229 
  230                 /* configure port 0 as serial port
  231                    (should already be after reset) */
  232                 cd_write_reg_sc(sc, cy_chip, CD1400_GCR, 0);
  233 
  234                 /* Set cy_clock depending on firmware version */
  235                 if (cd_read_reg_sc(sc, cy_chip, CD1400_GFRCR) <= 0x46)
  236                         cy_clock = CY_CLOCK;
  237                 else 
  238                         cy_clock = CY_CLOCK_60;
  239 
  240                 /* set up a receive timeout period (1ms) */
  241                 cd_write_reg_sc(sc, cy_chip, CD1400_PPR,
  242                     (cy_clock / CD1400_PPR_PRESCALER / 1000) + 1);
  243 
  244                 for (cdu = 0; cdu < CD1400_NO_OF_CHANNELS; cdu++) {
  245                         sc->sc_ports[port].cy_port_num = port;
  246                         sc->sc_ports[port].cy_memt = sc->sc_memt;
  247                         sc->sc_ports[port].cy_memh = sc->sc_memh;
  248                         sc->sc_ports[port].cy_chip_offs = chip_offs;
  249                         sc->sc_ports[port].cy_bustype = sc->sc_bustype;
  250                         sc->sc_ports[port].cy_clock = cy_clock;
  251 
  252                         /* should we initialize anything else here? */
  253                         port++;
  254                 } /* for(each port on one CD1400...) */
  255 
  256         } /* for(each CD1400 on a card... ) */
  257 
  258         printf(": %d ports\n", port);
  259 
  260         /* ensure an edge for the next interrupt */
  261         bus_space_write_1(sc->sc_memt, sc->sc_memh,
  262             CY_CLEAR_INTR<<sc->sc_bustype, 0);
  263 }
  264 
  265 /*
  266  * open routine. returns zero if successful, else error code
  267  */
  268 int cyopen(dev_t, int, int, struct proc *);
  269 int cyclose(dev_t, int, int, struct proc *);
  270 int cyread(dev_t, struct uio *, int);
  271 int cywrite(dev_t, struct uio *, int);
  272 struct tty *cytty(dev_t);
  273 int cyioctl(dev_t, u_long, caddr_t, int, struct proc *);
  274 int cystop(struct tty *, int flag);
  275 
  276 int
  277 cyopen(dev, flag, mode, p)
  278         dev_t dev;
  279         int flag, mode;
  280         struct proc *p;
  281 {
  282         int card = CY_CARD(dev);
  283         int port = CY_PORT(dev);
  284         struct cy_softc *sc;
  285         struct cy_port *cy;
  286         struct tty *tp;
  287         int s, error;
  288 
  289         if (card >= cy_cd.cd_ndevs ||
  290             (sc = cy_cd.cd_devs[card]) == NULL) {
  291                 return (ENXIO);
  292         }
  293 
  294 #ifdef CY_DEBUG
  295         printf("%s open port %d flag 0x%x mode 0x%x\n", sc->sc_dev.dv_xname,
  296             port, flag, mode);
  297 #endif
  298 
  299         cy = &sc->sc_ports[port];
  300 
  301         s = spltty();
  302         if (cy->cy_tty == NULL) {
  303                 cy->cy_tty = ttymalloc();
  304         }
  305         splx(s);
  306 
  307         tp = cy->cy_tty;
  308         tp->t_oproc = cystart;
  309         tp->t_param = cyparam;
  310         tp->t_dev = dev;
  311 
  312         if (!ISSET(tp->t_state, TS_ISOPEN)) {
  313                 SET(tp->t_state, TS_WOPEN);
  314                 ttychars(tp);
  315                 tp->t_iflag = TTYDEF_IFLAG;
  316                 tp->t_oflag = TTYDEF_OFLAG;
  317                 tp->t_cflag = TTYDEF_CFLAG;
  318                 if (ISSET(cy->cy_openflags, TIOCFLAG_CLOCAL))
  319                         SET(tp->t_cflag, CLOCAL);
  320                 if (ISSET(cy->cy_openflags, TIOCFLAG_CRTSCTS))
  321                         SET(tp->t_cflag, CRTSCTS);
  322                 if (ISSET(cy->cy_openflags, TIOCFLAG_MDMBUF))
  323                         SET(tp->t_cflag, MDMBUF);
  324                 tp->t_lflag = TTYDEF_LFLAG;
  325                 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
  326 
  327                 s = spltty();
  328 
  329                 /*
  330                  * Allocate input ring buffer if we don't already have one
  331                  */
  332                 if (cy->cy_ibuf == NULL) {
  333                         cy->cy_ibuf = malloc(IBUF_SIZE, M_DEVBUF, M_NOWAIT);
  334                         if (cy->cy_ibuf == NULL) {
  335                                 printf("%s: (port %d) can't allocate input buffer\n",
  336                                        sc->sc_dev.dv_xname, port);
  337                                 splx(s);
  338                                 return (ENOMEM);
  339                         }
  340                         cy->cy_ibuf_end = cy->cy_ibuf + IBUF_SIZE;
  341                 }
  342 
  343                 /* mark the ring buffer as empty */
  344                 cy->cy_ibuf_rd_ptr = cy->cy_ibuf_wr_ptr = cy->cy_ibuf;
  345 
  346                 /* select CD1400 channel */
  347                 cd_write_reg(cy, CD1400_CAR, port & CD1400_CAR_CHAN);
  348                 /* reset the channel */
  349                 cd1400_channel_cmd(cy, CD1400_CCR_CMDRESET);
  350                 /* encode unit (port) number in LIVR */
  351                 /* there is just enough space for 5 bits (32 ports) */
  352                 cd_write_reg(cy, CD1400_LIVR, port << 3);
  353 
  354                 cy->cy_channel_control = 0;
  355 
  356                 if (!timeout_pending(&sc->sc_poll_to))
  357                         timeout_add(&sc->sc_poll_to, 1);
  358 
  359                 /* this sets parameters and raises DTR */
  360                 cyparam(tp, &tp->t_termios);
  361 
  362                 ttsetwater(tp);
  363 
  364                 /* raise RTS too */
  365                 cy_modem_control(cy, TIOCM_RTS, DMBIS);
  366 
  367                 cy->cy_carrier_stat = cd_read_reg(cy, CD1400_MSVR2);
  368 
  369                 /* enable receiver and modem change interrupts */
  370                 cd_write_reg(cy, CD1400_SRER,
  371                     CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
  372 
  373                 if (CY_DIALOUT(dev) ||
  374                     ISSET(cy->cy_openflags, TIOCFLAG_SOFTCAR) ||
  375                     ISSET(tp->t_cflag, MDMBUF) ||
  376                     ISSET(cy->cy_carrier_stat, CD1400_MSVR2_CD))
  377                         SET(tp->t_state, TS_CARR_ON);
  378                 else
  379                         CLR(tp->t_state, TS_CARR_ON);
  380         } else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0) {
  381                 return (EBUSY);
  382         } else {
  383                 s = spltty();
  384         }
  385 
  386         /* wait for carrier if necessary */
  387         if (!ISSET(flag, O_NONBLOCK)) {
  388                 while (!ISSET(tp->t_cflag, CLOCAL) &&
  389                     !ISSET(tp->t_state, TS_CARR_ON)) {
  390                         SET(tp->t_state, TS_WOPEN);
  391                         error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
  392                             "cydcd", 0);
  393                         if (error != 0) {
  394                                 splx(s);
  395                                 CLR(tp->t_state, TS_WOPEN);
  396                                 return (error);
  397                         }
  398                 }
  399         }
  400 
  401         splx(s);
  402 
  403         return (*linesw[tp->t_line].l_open)(dev, tp);
  404 }
  405 
  406 /*
  407  * close routine. returns zero if successful, else error code
  408  */
  409 int
  410 cyclose(dev, flag, mode, p)
  411         dev_t dev;
  412         int flag, mode;
  413         struct proc *p;
  414 {
  415         int card = CY_CARD(dev);
  416         int port = CY_PORT(dev);
  417         struct cy_softc *sc = cy_cd.cd_devs[card];
  418         struct cy_port *cy = &sc->sc_ports[port];
  419         struct tty *tp = cy->cy_tty;
  420         int s;
  421 
  422 #ifdef CY_DEBUG
  423         printf("%s close port %d, flag 0x%x, mode 0x%x\n", sc->sc_dev.dv_xname,
  424             port, flag, mode);
  425 #endif
  426 
  427         (*linesw[tp->t_line].l_close)(tp, flag);
  428         s = spltty();
  429 
  430         if (ISSET(tp->t_cflag, HUPCL) &&
  431             !ISSET(cy->cy_openflags, TIOCFLAG_SOFTCAR)) {
  432                 /* drop DTR and RTS
  433                    (should we wait for output buffer to become empty first?) */
  434                 cy_modem_control(cy, 0, DMSET);
  435         }
  436 
  437         /*
  438          * XXX should we disable modem change and
  439          * receive interrupts here or somewhere ?
  440          */
  441         CLR(tp->t_state, TS_BUSY | TS_FLUSH);
  442 
  443         splx(s);
  444         ttyclose(tp);
  445 
  446         return (0);
  447 }
  448 
  449 /*
  450  * Read routine
  451  */
  452 int
  453 cyread(dev, uio, flag)
  454         dev_t dev;
  455         struct uio *uio;
  456         int flag;
  457 {
  458         int card = CY_CARD(dev);
  459         int port = CY_PORT(dev);
  460         struct cy_softc *sc = cy_cd.cd_devs[card];
  461         struct cy_port *cy = &sc->sc_ports[port];
  462         struct tty *tp = cy->cy_tty;
  463 
  464 #ifdef CY_DEBUG
  465         printf("%s read port %d uio 0x%x flag 0x%x\n", sc->sc_dev.dv_xname,
  466             port, uio, flag);
  467 #endif
  468 
  469         return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
  470 }
  471 
  472 /*
  473  * Write routine
  474  */
  475 int
  476 cywrite(dev, uio, flag)
  477         dev_t dev;
  478         struct uio *uio;
  479         int flag;
  480 {
  481         int card = CY_CARD(dev);
  482         int port = CY_PORT(dev);
  483         struct cy_softc *sc = cy_cd.cd_devs[card];
  484         struct cy_port *cy = &sc->sc_ports[port];
  485         struct tty *tp = cy->cy_tty;
  486 
  487 #ifdef CY_DEBUG
  488         printf("%s write port %d uio 0x%x flag 0x%x\n", sc->sc_dev.dv_xname,
  489             port, uio, flag);
  490 #endif
  491 
  492         return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
  493 }
  494 
  495 /*
  496  * return tty pointer
  497  */
  498 struct tty *
  499 cytty(dev)
  500         dev_t dev;
  501 {
  502         int card = CY_CARD(dev);
  503         int port = CY_PORT(dev);
  504         struct cy_softc *sc = cy_cd.cd_devs[card];
  505         struct cy_port *cy = &sc->sc_ports[port];
  506         struct tty *tp = cy->cy_tty;
  507 
  508         return (tp);
  509 }
  510 
  511 /*
  512  * ioctl routine
  513  */
  514 int
  515 cyioctl(dev, cmd, data, flag, p)
  516         dev_t dev;
  517         u_long cmd;
  518         caddr_t data;
  519         int flag;
  520         struct proc *p;
  521 {
  522         int card = CY_CARD(dev);
  523         int port = CY_PORT(dev);
  524         struct cy_softc *sc = cy_cd.cd_devs[card];
  525         struct cy_port *cy = &sc->sc_ports[port];
  526         struct tty *tp = cy->cy_tty;
  527         int error;
  528 
  529 #ifdef CY_DEBUG
  530         printf("%s port %d ioctl cmd 0x%x data 0x%x flag 0x%x\n",
  531             sc->sc_dev.dv_xname, port, cmd, data, flag);
  532 #endif
  533 
  534         error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
  535         if (error >= 0)
  536                 return (error);
  537 
  538         error = ttioctl(tp, cmd, data, flag, p);
  539         if (error >= 0)
  540                 return (error);
  541 
  542         /* XXX should not allow dropping DTR when dialin? */
  543 
  544         switch (cmd) {
  545         case TIOCSBRK:          /* start break */
  546                 SET(cy->cy_flags, CYF_START_BREAK);
  547                 cy_enable_transmitter(cy);
  548                 break;
  549 
  550         case TIOCCBRK:          /* stop break */
  551                 SET(cy->cy_flags, CYF_END_BREAK);
  552                 cy_enable_transmitter(cy);
  553                 break;
  554 
  555         case TIOCSDTR:          /* DTR on */
  556                 cy_modem_control(cy, TIOCM_DTR, DMBIS);
  557                 break;
  558 
  559         case TIOCCDTR:          /* DTR off */
  560                 cy_modem_control(cy, TIOCM_DTR, DMBIC);
  561                 break;
  562 
  563         case TIOCMSET:          /* set new modem control line values */
  564                 cy_modem_control(cy, *((int *)data), DMSET);
  565                 break;
  566 
  567         case TIOCMBIS:          /* turn modem control bits on */
  568                 cy_modem_control(cy, *((int *)data), DMBIS);
  569                 break;
  570 
  571         case TIOCMBIC:          /* turn modem control bits off */
  572                 cy_modem_control(cy, *((int *)data), DMBIC);
  573                 break;
  574 
  575         case TIOCMGET:          /* get modem control/status line state */
  576                 *((int *)data) = cy_modem_control(cy, 0, DMGET);
  577                 break;
  578 
  579         case TIOCGFLAGS:
  580                 *((int *)data) = cy->cy_openflags |
  581                     (CY_DIALOUT(dev) ? TIOCFLAG_SOFTCAR : 0);
  582                 break;
  583 
  584         case TIOCSFLAGS:
  585                 error = suser(p, 0);
  586                 if (error != 0)
  587                         return (EPERM);
  588 
  589                 cy->cy_openflags = *((int *)data) &
  590                     (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL |
  591                      TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF);
  592                 break;
  593 
  594         default:
  595                 return (ENOTTY);
  596         }
  597 
  598         return (0);
  599 }
  600 
  601 /*
  602  * start output
  603  */
  604 void
  605 cystart(tp)
  606         struct tty *tp;
  607 {
  608         int card = CY_CARD(tp->t_dev);
  609         int port = CY_PORT(tp->t_dev);
  610         struct cy_softc *sc = cy_cd.cd_devs[card];
  611         struct cy_port *cy = &sc->sc_ports[port];
  612         int s;
  613 
  614 #ifdef CY_DEBUG
  615         printf("%s port %d start, tty 0x%x\n", sc->sc_dev.dv_xname, port, tp);
  616 #endif
  617 
  618         s = spltty();
  619 
  620 #ifdef CY_DEBUG1
  621         cy->cy_start_count++;
  622 #endif
  623 
  624         if (!ISSET(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) {
  625                 if (tp->t_outq.c_cc <= tp->t_lowat) {
  626                         if (ISSET(tp->t_state, TS_ASLEEP)) {
  627                                 CLR(tp->t_state, TS_ASLEEP);
  628                                 wakeup(&tp->t_outq);
  629                         }
  630 
  631                         selwakeup(&tp->t_wsel);
  632 
  633                         if (tp->t_outq.c_cc == 0)
  634                                 goto out;
  635                 }
  636 
  637                 SET(tp->t_state, TS_BUSY);
  638                 cy_enable_transmitter(cy);
  639         }
  640 out:
  641 
  642         splx(s);
  643 }
  644 
  645 /*
  646  * stop output
  647  */
  648 int
  649 cystop(tp, flag)
  650         struct tty *tp;
  651         int flag;
  652 {
  653         int card = CY_CARD(tp->t_dev);
  654         int port = CY_PORT(tp->t_dev);
  655         struct cy_softc *sc = cy_cd.cd_devs[card];
  656         struct cy_port *cy = &sc->sc_ports[port];
  657         int s;
  658 
  659 #ifdef CY_DEBUG
  660         printf("%s port %d stop tty 0x%x flag 0x%x\n", sc->sc_dev.dv_xname,
  661             port, tp, flag);
  662 #endif
  663 
  664         s = spltty();
  665 
  666         if (ISSET(tp->t_state, TS_BUSY)) {
  667                 if (!ISSET(tp->t_state, TS_TTSTOP))
  668                         SET(tp->t_state, TS_FLUSH);
  669 
  670                 /*
  671                  * the transmit interrupt routine will disable transmit when it
  672                  * notices that CYF_STOP has been set.
  673                  */
  674                 SET(cy->cy_flags, CYF_STOP);
  675         }
  676         splx(s);
  677         return (0);
  678 }
  679 
  680 /*
  681  * parameter setting routine.
  682  * returns 0 if successful, else returns error code
  683  */
  684 int
  685 cyparam(tp, t)
  686         struct tty *tp;
  687         struct termios *t;
  688 {
  689         int card = CY_CARD(tp->t_dev);
  690         int port = CY_PORT(tp->t_dev);
  691         struct cy_softc *sc = cy_cd.cd_devs[card];
  692         struct cy_port *cy = &sc->sc_ports[port];
  693         int ibpr, obpr, i_clk_opt, o_clk_opt;
  694         int s, opt;
  695 
  696 #ifdef CY_DEBUG
  697         printf("%s port %d param tty 0x%x termios 0x%x\n", sc->sc_dev.dv_xname,
  698             port, tp, t);
  699         printf("ispeed %d ospeed %d\n", t->c_ispeed, t->c_ospeed);
  700 #endif
  701 
  702         if (t->c_ospeed != 0 &&
  703             cy_speed(t->c_ospeed, &o_clk_opt, &obpr, cy->cy_clock) < 0)
  704                 return (EINVAL);
  705 
  706         if (t->c_ispeed != 0 &&
  707             cy_speed(t->c_ispeed, &i_clk_opt, &ibpr, cy->cy_clock) < 0)
  708                 return (EINVAL);
  709 
  710         s = spltty();
  711 
  712         /* hang up the line is ospeed is zero, else turn DTR on */
  713         cy_modem_control(cy, TIOCM_DTR, (t->c_ospeed == 0 ? DMBIC : DMBIS));
  714 
  715         /* channel was selected by the above call to cy_modem_control() */
  716         /* cd_write_reg(cy, CD1400_CAR, port & CD1400_CAR_CHAN); */
  717 
  718         /* set transmit speed */
  719         if (t->c_ospeed != 0) {
  720                 cd_write_reg(cy, CD1400_TCOR, o_clk_opt);
  721                 cd_write_reg(cy, CD1400_TBPR, obpr);
  722         }
  723         /* set receive speed */
  724         if (t->c_ispeed != 0) {
  725                 cd_write_reg(cy, CD1400_RCOR, i_clk_opt);
  726                 cd_write_reg(cy, CD1400_RBPR, ibpr);
  727         }
  728 
  729         opt = CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTEN
  730             | (ISSET(t->c_cflag, CREAD) ? CD1400_CCR_RCVEN : CD1400_CCR_RCVDIS);
  731 
  732         if (opt != cy->cy_channel_control) {
  733                 cy->cy_channel_control = opt;
  734                 cd1400_channel_cmd(cy, opt);
  735         }
  736 
  737         /* compute COR1 contents */
  738         opt = 0;
  739         if (ISSET(t->c_cflag, PARENB)) {
  740                 if (ISSET(t->c_cflag, PARODD))
  741                         opt |= CD1400_COR1_PARODD;
  742                 opt |= CD1400_COR1_PARNORMAL;
  743         }
  744 
  745         if (!ISSET(t->c_iflag, INPCK))
  746                 opt |= CD1400_COR1_NOINPCK;     /* no parity checking */
  747 
  748         if (ISSET(t->c_cflag, CSTOPB))
  749                 opt |= CD1400_COR1_STOP2;
  750 
  751         switch (t->c_cflag & CSIZE) {
  752         case CS5:
  753                 opt |= CD1400_COR1_CS5;
  754                 break;
  755 
  756         case CS6:
  757                 opt |= CD1400_COR1_CS6;
  758                 break;
  759 
  760         case CS7:
  761                 opt |= CD1400_COR1_CS7;
  762                 break;
  763 
  764         default:
  765                 opt |= CD1400_COR1_CS8;
  766                 break;
  767         }
  768 
  769         cd_write_reg(cy, CD1400_COR1, opt);
  770 
  771 #ifdef CY_DEBUG
  772         printf("cor1 = 0x%x...", opt);
  773 #endif
  774 
  775         /*
  776          * use the CD1400 automatic CTS flow control if CRTSCTS is set
  777          *
  778          * CD1400_COR2_ETC is used because breaks are generated with
  779          * embedded transmit commands
  780          */
  781         cd_write_reg(cy, CD1400_COR2,
  782             CD1400_COR2_ETC |
  783             (ISSET(t->c_cflag, CRTSCTS) ? CD1400_COR2_CCTS_OFLOW : 0));
  784 
  785         cd_write_reg(cy, CD1400_COR3, RX_FIFO_THRESHOLD);
  786 
  787         cd1400_channel_cmd(cy,
  788             CD1400_CCR_CMDCORCHG |
  789             CD1400_CCR_COR1 | CD1400_CCR_COR2 | CD1400_CCR_COR3);
  790 
  791         cd_write_reg(cy, CD1400_COR4, CD1400_COR4_PFO_EXCEPTION);
  792         cd_write_reg(cy, CD1400_COR5, 0);
  793 
  794         /*
  795          * set modem change option registers to generate interrupts
  796          * on carrier detect changes.
  797          *
  798          * if hardware RTS handshaking is used (CY_HW_RTS, DTR and RTS lines
  799          * exchanged), also set the handshaking threshold.
  800          */
  801 #ifdef CY_HW_RTS
  802         cd_write_reg(cy, CD1400_MCOR1, CD1400_MCOR1_CDzd |
  803             (ISSET(t->c_cflag, CRTSCTS) ? RX_DTR_THRESHOLD : 0));
  804 #else
  805         cd_write_reg(cy, CD1400_MCOR1, CD1400_MCOR1_CDzd);
  806 #endif /* CY_HW_RTS */
  807 
  808         cd_write_reg(cy, CD1400_MCOR2, CD1400_MCOR2_CDod);
  809 
  810         /*
  811          * set receive timeout to approx. 2ms
  812          * could use more complex logic here...
  813          * (but is it actually needed or even useful?)
  814          */
  815         cd_write_reg(cy, CD1400_RTPR, 2);
  816 
  817         /*
  818          * should do anything else here?
  819          * XXX check MDMBUF handshaking like in com.c?
  820          */
  821 
  822         splx(s);
  823         return (0);
  824 }
  825 
  826 /*
  827  * set/get modem line status
  828  *
  829  * bits can be: TIOCM_DTR, TIOCM_RTS, TIOCM_CTS, TIOCM_CD, TIOCM_RI, TIOCM_DSR
  830  *
  831  * RTS and DTR are exchanged if CY_HW_RTS is set
  832  *
  833  */
  834 int
  835 cy_modem_control(cy, bits, howto)
  836         struct cy_port *cy;
  837         int bits;
  838         int howto;
  839 {
  840         int s, msvr;
  841 
  842         s = spltty();
  843 
  844         /* select channel */
  845         cd_write_reg(cy, CD1400_CAR, cy->cy_port_num & CD1400_CAR_CHAN);
  846 
  847 /* does not manipulate RTS if it is used for flow control */
  848         switch (howto) {
  849         case DMGET:
  850                 bits = 0;
  851                 if (cy->cy_channel_control & CD1400_CCR_RCVEN)
  852                         bits |= TIOCM_LE;
  853                 msvr = cd_read_reg(cy, CD1400_MSVR2);
  854 #ifdef CY_HW_RTS
  855                 if (cd_read_reg(cy, CD1400_MSVR1) & CD1400_MSVR1_RTS)
  856                         bits |= TIOCM_DTR;
  857                 if (msvr & CD1400_MSVR2_DTR)
  858                         bits |= TIOCM_RTS;
  859 #else
  860                 if (cd_read_reg(cy, CD1400_MSVR1) & CD1400_MSVR1_RTS)
  861                         bits |= TIOCM_RTS;
  862                 if (msvr & CD1400_MSVR2_DTR)
  863                         bits |= TIOCM_DTR;
  864 #endif /* CY_HW_RTS */
  865                 if (msvr & CD1400_MSVR2_CTS)
  866                         bits |= TIOCM_CTS;
  867                 if (msvr & CD1400_MSVR2_CD)
  868                         bits |= TIOCM_CD;
  869                 if (msvr & CD1400_MSVR2_DSR)    /* not connected on some
  870                                                    Cyclom cards? */
  871                         bits |= TIOCM_DSR;
  872                 if (msvr & CD1400_MSVR2_RI)     /* not connected on
  873                                                    Cyclom-8Y cards? */
  874                         bits |= TIOCM_RI;
  875                 splx(s);
  876                 return (bits);
  877 
  878         case DMSET: /* replace old values with new ones */
  879 #ifdef CY_HW_RTS
  880                 if (!ISSET(cy->cy_tty->t_cflag, CRTSCTS))
  881                         cd_write_reg(cy, CD1400_MSVR2,
  882                             ((bits & TIOCM_RTS) ? CD1400_MSVR2_DTR : 0));
  883                 cd_write_reg(cy, CD1400_MSVR1,
  884                     ((bits & TIOCM_DTR) ? CD1400_MSVR1_RTS : 0));
  885 #else
  886                 if (!ISSET(cy->cy_tty->t_cflag, CRTSCTS))
  887                         cd_write_reg(cy, CD1400_MSVR1,
  888                             ((bits & TIOCM_RTS) ? CD1400_MSVR1_RTS : 0));
  889                 cd_write_reg(cy, CD1400_MSVR2,
  890                     ((bits & TIOCM_DTR) ? CD1400_MSVR2_DTR : 0));
  891 #endif /* CY_HW_RTS */
  892                 break;
  893 
  894         case DMBIS: /* set bits */
  895 #ifdef CY_HW_RTS
  896                 if (!ISSET(cy->cy_tty->t_cflag, CRTSCTS) &&
  897                     (bits & TIOCM_RTS) != 0)
  898                         cd_write_reg(cy, CD1400_MSVR2, CD1400_MSVR2_DTR);
  899                 if (bits & TIOCM_DTR)
  900                         cd_write_reg(cy, CD1400_MSVR1, CD1400_MSVR1_RTS);
  901 #else
  902                 if (!ISSET(cy->cy_tty->t_cflag, CRTSCTS) &&
  903                     (bits & TIOCM_RTS) != 0)
  904                         cd_write_reg(cy, CD1400_MSVR1, CD1400_MSVR1_RTS);
  905                 if (bits & TIOCM_DTR)
  906                         cd_write_reg(cy, CD1400_MSVR2, CD1400_MSVR2_DTR);
  907 #endif /* CY_HW_RTS */
  908                 break;
  909 
  910         case DMBIC: /* clear bits */
  911 #ifdef CY_HW_RTS
  912                 if (!ISSET(cy->cy_tty->t_cflag, CRTSCTS) &&
  913                     (bits & TIOCM_RTS))
  914                         cd_write_reg(cy, CD1400_MSVR2, 0);
  915                 if (bits & TIOCM_DTR)
  916                         cd_write_reg(cy, CD1400_MSVR1, 0);
  917 #else
  918                 if (!ISSET(cy->cy_tty->t_cflag, CRTSCTS) &&
  919                     (bits & TIOCM_RTS))
  920                         cd_write_reg(cy, CD1400_MSVR1, 0);
  921                 if (bits & TIOCM_DTR)
  922                         cd_write_reg(cy, CD1400_MSVR2, 0);
  923 #endif /* CY_HW_RTS */
  924                 break;
  925         }
  926         splx(s);
  927         return (0);
  928 }
  929 
  930 /*
  931  * Upper-level handler loop (called from timer interrupt?)
  932  * This routine is common for multiple cards
  933  */
  934 void
  935 cy_poll(void *arg)
  936 {
  937         int port;
  938         struct cy_softc *sc = arg;
  939         struct cy_port *cy;
  940         struct tty *tp;
  941         static int counter = 0;
  942 #ifdef CY_DEBUG1
  943         int did_something;
  944 #endif
  945 
  946         int s;
  947 
  948         s = spltty();
  949 
  950         if (sc->sc_events == 0 && ++counter < 200) {
  951                 splx(s);
  952                 goto out;
  953         }
  954 
  955         sc->sc_events = 0;
  956         splx(s);
  957 
  958 #ifdef CY_DEBUG1
  959         sc->sc_poll_count1++;
  960         did_something = 0;
  961 #endif
  962 
  963         for (port = 0; port < sc->sc_nports; port++) {
  964                 cy = &sc->sc_ports[port];
  965                 if ((tp = cy->cy_tty) == NULL || cy->cy_ibuf == NULL ||
  966                     !ISSET(tp->t_state, TS_ISOPEN | TS_WOPEN))
  967                         continue;
  968 
  969                 /*
  970                  * handle received data
  971                  */
  972                 while (cy->cy_ibuf_rd_ptr != cy->cy_ibuf_wr_ptr) {
  973                         u_char line_stat;
  974                         int chr;
  975 
  976                         line_stat = cy->cy_ibuf_rd_ptr[0];
  977                         chr = cy->cy_ibuf_rd_ptr[1];
  978 
  979                         if (line_stat &
  980                             (CD1400_RDSR_BREAK|CD1400_RDSR_FE))
  981                                 chr |= TTY_FE;
  982                         if (line_stat & CD1400_RDSR_PE)
  983                                 chr |= TTY_PE;
  984 
  985                         /*
  986                          * on an overrun error the data is treated as
  987                          * good just as it should be.
  988                          */
  989 
  990 #ifdef CY_DEBUG
  991                         printf("%s port %d ttyinput 0x%x\n",
  992                             sc->sc_dev.dv_xname, port, chr);
  993 #endif
  994 
  995                         (*linesw[tp->t_line].l_rint)(chr, tp);
  996 
  997                         s = spltty(); /* really necessary? */
  998                         if ((cy->cy_ibuf_rd_ptr += 2) ==
  999                             cy->cy_ibuf_end)
 1000                                 cy->cy_ibuf_rd_ptr = cy->cy_ibuf;
 1001                         splx(s);
 1002 
 1003 #ifdef CY_DEBUG1
 1004                         did_something = 1;
 1005 #endif
 1006                 }
 1007 
 1008 #ifndef CY_HW_RTS
 1009                 /*
 1010                  * If we don't have any received data in ibuf and
 1011                  * CRTSCTS is on and RTS is turned off, it is time
 1012                  * to turn RTS back on
 1013                  */
 1014                 if (ISSET(tp->t_cflag, CRTSCTS)) {
 1015                         /* we can't use cy_modem_control() here as it
 1016                             doesn't change RTS if RTSCTS is on */
 1017                         cd_write_reg(cy, CD1400_CAR,
 1018                             port & CD1400_CAR_CHAN);
 1019               
 1020                         if ((cd_read_reg(cy,
 1021                             CD1400_MSVR1) & CD1400_MSVR1_RTS) == 0) {
 1022                                 cd_write_reg(cy, CD1400_MSVR1,
 1023                                     CD1400_MSVR1_RTS);
 1024 #ifdef CY_DEBUG1
 1025                                 did_something = 1;
 1026 #endif
 1027                         }
 1028                 }
 1029 #endif /* CY_HW_RTS */
 1030 
 1031                 /*
 1032                  * handle carrier changes
 1033                  */
 1034                 s = spltty();
 1035                 if (ISSET(cy->cy_flags, CYF_CARRIER_CHANGED)) {
 1036                         int carrier;
 1037 
 1038                         CLR(cy->cy_flags, CYF_CARRIER_CHANGED);
 1039                         splx(s);
 1040 
 1041                         carrier = ((cy->cy_carrier_stat &
 1042                             CD1400_MSVR2_CD) != 0);
 1043 
 1044 #ifdef CY_DEBUG
 1045                         printf("%s: cy_poll: carrier change "
 1046                             "(port %d, carrier %d)\n",
 1047                             sc->sc_dev.dv_xname, port, carrier);
 1048 #endif
 1049                         if (CY_DIALIN(tp->t_dev) &&
 1050                             !(*linesw[tp->t_line].l_modem)(tp, carrier))
 1051                                 cy_modem_control(cy, TIOCM_DTR, DMBIC);
 1052 
 1053 #ifdef CY_DEBUG1
 1054                         did_something = 1;
 1055 #endif
 1056                 } else {
 1057                         splx(s);
 1058                 }
 1059 
 1060                 s = spltty();
 1061                 if (ISSET(cy->cy_flags, CYF_START)) {
 1062                         CLR(cy->cy_flags, CYF_START);
 1063                         splx(s);
 1064 
 1065                         (*linesw[tp->t_line].l_start)(tp);
 1066 
 1067 #ifdef CY_DEBUG1
 1068                         did_something = 1;
 1069 #endif
 1070                 } else {
 1071                         splx(s);
 1072                 }
 1073 
 1074                 /* could move this to even upper level... */
 1075                 if (cy->cy_fifo_overruns) {
 1076                         cy->cy_fifo_overruns = 0;
 1077                         /* doesn't report overrun count,
 1078                            but shouldn't really matter */
 1079                         log(LOG_WARNING, "%s: port %d fifo overrun\n",
 1080                             sc->sc_dev.dv_xname, port);
 1081                 }
 1082                 if (cy->cy_ibuf_overruns) {
 1083                         cy->cy_ibuf_overruns = 0;
 1084                         log(LOG_WARNING, "%s: port %d ibuf overrun\n",
 1085                             sc->sc_dev.dv_xname, port);
 1086                 }
 1087         } /* for(port...) */
 1088 #ifdef CY_DEBUG1
 1089         if (did_something && counter >= 200)
 1090                 sc->sc_poll_count2++;
 1091 #endif
 1092 
 1093         counter = 0;
 1094 
 1095 out:
 1096         timeout_add(&sc->sc_poll_to, 1);
 1097 }
 1098 
 1099 /*
 1100  * hardware interrupt routine
 1101  */
 1102 int
 1103 cy_intr(arg)
 1104         void *arg;
 1105 {
 1106         struct cy_softc *sc = arg;
 1107         struct cy_port *cy;
 1108         int cy_chip, stat;
 1109         int int_serviced = -1;
 1110 
 1111         /*
 1112          * Check interrupt status of each CD1400 chip on this card
 1113          * (multiple cards cannot share the same interrupt)
 1114          */
 1115         for (cy_chip = 0; cy_chip < sc->sc_nr_cd1400s; cy_chip++) {
 1116 
 1117                 stat = cd_read_reg_sc(sc, cy_chip, CD1400_SVRR);
 1118                 if (stat == 0)
 1119                         continue;
 1120 
 1121                 if (ISSET(stat, CD1400_SVRR_RXRDY)) {
 1122                         u_char save_car, save_rir, serv_type;
 1123                         u_char line_stat, recv_data, n_chars;
 1124                         u_char *buf_p;
 1125 
 1126                         save_rir = cd_read_reg_sc(sc, cy_chip, CD1400_RIR);
 1127                         save_car = cd_read_reg_sc(sc, cy_chip, CD1400_CAR);
 1128                         /* enter rx service */
 1129                         cd_write_reg_sc(sc, cy_chip, CD1400_CAR, save_rir);
 1130 
 1131                         serv_type = cd_read_reg_sc(sc, cy_chip, CD1400_RIVR);
 1132                         cy = &sc->sc_ports[serv_type >> 3];
 1133 
 1134 #ifdef CY_DEBUG1
 1135                         cy->cy_rx_int_count++;
 1136 #endif
 1137 
 1138                         buf_p = cy->cy_ibuf_wr_ptr;
 1139 
 1140                         if (ISSET(serv_type, CD1400_RIVR_EXCEPTION)) {
 1141                                 line_stat = cd_read_reg(cy, CD1400_RDSR);
 1142                                 recv_data = cd_read_reg(cy, CD1400_RDSR);
 1143 
 1144                                 if (cy->cy_tty == NULL ||
 1145                                     !ISSET(cy->cy_tty->t_state, TS_ISOPEN))
 1146                                         goto end_rx_serv;
 1147 
 1148 #ifdef CY_DEBUG
 1149                                 printf("%s port %d recv exception, "
 1150                                     "line_stat 0x%x, char 0x%x\n",
 1151                                     sc->sc_dev.dv_xname, cy->cy_port_num,
 1152                                     line_stat, recv_data);
 1153 #endif
 1154                                 if (ISSET(line_stat, CD1400_RDSR_OE))
 1155                                         cy->cy_fifo_overruns++;
 1156 
 1157                                 *buf_p++ = line_stat;
 1158                                 *buf_p++ = recv_data;
 1159                                 if (buf_p == cy->cy_ibuf_end)
 1160                                         buf_p = cy->cy_ibuf;
 1161 
 1162                                 if (buf_p == cy->cy_ibuf_rd_ptr) {
 1163                                         if (buf_p == cy->cy_ibuf)
 1164                                                 buf_p = cy->cy_ibuf_end;
 1165                                         buf_p -= 2;
 1166                                         cy->cy_ibuf_overruns++;
 1167                                 }
 1168                                 sc->sc_events = 1;
 1169                         } else { /* no exception, received data OK */
 1170                                 n_chars = cd_read_reg(cy, CD1400_RDCR);
 1171 
 1172                                 /* If no tty or not open, discard data */
 1173                                 if (cy->cy_tty == NULL ||
 1174                                     !ISSET(cy->cy_tty->t_state, TS_ISOPEN)) {
 1175                                         while (n_chars--)
 1176                                                 cd_read_reg(cy, CD1400_RDSR);
 1177                                         goto end_rx_serv;
 1178                                 }
 1179 
 1180 #ifdef CY_DEBUG
 1181                                 printf("%s port %d receive ok %d chars\n",
 1182                                     sc->sc_dev.dv_xname, cy->cy_port_num,
 1183                                     n_chars);
 1184 #endif
 1185                                 while (n_chars--) {
 1186                                         *buf_p++ = 0; /* status: OK */
 1187                                         *buf_p++ = cd_read_reg(cy,
 1188                                             CD1400_RDSR); /* data byte */
 1189                                         if (buf_p == cy->cy_ibuf_end)
 1190                                                 buf_p = cy->cy_ibuf;
 1191                                         if (buf_p == cy->cy_ibuf_rd_ptr) {
 1192                                                 if (buf_p == cy->cy_ibuf)
 1193                                                         buf_p = cy->cy_ibuf_end;
 1194                                                 buf_p -= 2;
 1195                                                 cy->cy_ibuf_overruns++;
 1196                                                 break;
 1197                                         }
 1198                                 }
 1199                                 sc->sc_events = 1;
 1200                         }
 1201 
 1202                         cy->cy_ibuf_wr_ptr = buf_p;
 1203 
 1204 #ifndef CY_HW_RTS
 1205                         /* RTS handshaking for incoming data */
 1206                         if (ISSET(cy->cy_tty->t_cflag, CRTSCTS)) {
 1207                                 int bf;
 1208 
 1209                                 bf = buf_p - cy->cy_ibuf_rd_ptr;
 1210                                 if (bf < 0)
 1211                                         bf += IBUF_SIZE;
 1212 
 1213                                 if (bf > (IBUF_SIZE/2)) /* turn RTS off */
 1214                                         cd_write_reg(cy, CD1400_MSVR1, 0);
 1215                         }
 1216 #endif /* CY_HW_RTS */
 1217 
 1218                 end_rx_serv:
 1219                         /* terminate service context */
 1220                         cd_write_reg(cy, CD1400_RIR, save_rir & 0x3f);
 1221                         cd_write_reg(cy, CD1400_CAR, save_car);
 1222                         int_serviced = 1;
 1223                 } /* if(rx_service...) */
 1224 
 1225                 if (ISSET(stat, CD1400_SVRR_MDMCH)) {
 1226                         u_char save_car, save_mir, serv_type, modem_stat;
 1227 
 1228                         save_mir = cd_read_reg_sc(sc, cy_chip, CD1400_MIR);
 1229                         save_car = cd_read_reg_sc(sc, cy_chip, CD1400_CAR);
 1230                         /* enter modem service */
 1231                         cd_write_reg_sc(sc, cy_chip, CD1400_CAR, save_mir);
 1232 
 1233                         serv_type = cd_read_reg_sc(sc, cy_chip, CD1400_MIVR);
 1234                         cy = &sc->sc_ports[serv_type >> 3];
 1235 
 1236 #ifdef CY_DEBUG1
 1237                         cy->cy_modem_int_count++;
 1238 #endif
 1239 
 1240                         modem_stat = cd_read_reg(cy, CD1400_MSVR2);
 1241 
 1242 #ifdef CY_DEBUG
 1243                         printf("%s port %d modem line change, new stat 0x%x\n",
 1244                             sc->sc_dev.dv_xname, cy->cy_port_num, modem_stat);
 1245 #endif
 1246                         if (ISSET((cy->cy_carrier_stat ^ modem_stat),
 1247                             CD1400_MSVR2_CD)) {
 1248                                 SET(cy->cy_flags, CYF_CARRIER_CHANGED);
 1249                                 sc->sc_events = 1;
 1250                         }
 1251 
 1252                         cy->cy_carrier_stat = modem_stat;
 1253 
 1254                         /* terminate service context */
 1255                         cd_write_reg(cy, CD1400_MIR, save_mir & 0x3f);
 1256                         cd_write_reg(cy, CD1400_CAR, save_car);
 1257                         int_serviced = 1;
 1258                 } /* if(modem_service...) */
 1259 
 1260                 if (ISSET(stat, CD1400_SVRR_TXRDY)) {
 1261                         u_char save_car, save_tir, serv_type, count, ch;
 1262                         struct tty *tp;
 1263 
 1264                         save_tir = cd_read_reg_sc(sc, cy_chip, CD1400_TIR);
 1265                         save_car = cd_read_reg_sc(sc, cy_chip, CD1400_CAR);
 1266                         /* enter tx service */
 1267                         cd_write_reg_sc(sc, cy_chip, CD1400_CAR, save_tir);
 1268 
 1269                         serv_type = cd_read_reg_sc(sc, cy_chip, CD1400_TIVR);
 1270                         cy = &sc->sc_ports[serv_type >> 3];
 1271 
 1272 #ifdef CY_DEBUG1
 1273                         cy->cy_tx_int_count++;
 1274 #endif
 1275 #ifdef CY_DEBUG
 1276                         printf("%s port %d tx service\n", sc->sc_dev.dv_xname,
 1277                             cy->cy_port_num);
 1278 #endif
 1279 
 1280                         /* stop transmitting if no tty or CYF_STOP set */
 1281                         tp = cy->cy_tty;
 1282                         if (tp == NULL || ISSET(cy->cy_flags, CYF_STOP))
 1283                                 goto txdone;
 1284 
 1285                         count = 0;
 1286                         if (ISSET(cy->cy_flags, CYF_SEND_NUL)) {
 1287                                 cd_write_reg(cy, CD1400_TDR, 0);
 1288                                 cd_write_reg(cy, CD1400_TDR, 0);
 1289                                 count += 2;
 1290                                 CLR(cy->cy_flags, CYF_SEND_NUL);
 1291                         }
 1292 
 1293                         if (tp->t_outq.c_cc > 0) {
 1294                                 SET(tp->t_state, TS_BUSY);
 1295                                 while (tp->t_outq.c_cc > 0 &&
 1296                                     count < CD1400_TX_FIFO_SIZE) {
 1297                                         ch = getc(&tp->t_outq);
 1298                                         /* remember to double NUL characters
 1299                                            because embedded transmit commands
 1300                                            are enabled */
 1301                                         if (ch == 0) {
 1302                                                 if (count >=
 1303                                                     CD1400_TX_FIFO_SIZE-2) {
 1304                                                         SET(cy->cy_flags,
 1305                                                             CYF_SEND_NUL);
 1306                                                         break;
 1307                                                 }
 1308 
 1309                                                 cd_write_reg(cy, CD1400_TDR, ch);
 1310                                                 count++;
 1311                                         }
 1312 
 1313                                         cd_write_reg(cy, CD1400_TDR, ch);
 1314                                         count++;
 1315                                 }
 1316                         } else {
 1317                                 /* no data to send -- check if we should
 1318                                    start/stop a break */
 1319                                 /* XXX does this cause too much delay before
 1320                                    breaks? */
 1321                                 if (ISSET(cy->cy_flags, CYF_START_BREAK)) {
 1322                                         cd_write_reg(cy, CD1400_TDR, 0);
 1323                                         cd_write_reg(cy, CD1400_TDR, 0x81);
 1324                                         CLR(cy->cy_flags, CYF_START_BREAK);
 1325                                 }
 1326                                 if (ISSET(cy->cy_flags, CYF_END_BREAK)) {
 1327                                         cd_write_reg(cy, CD1400_TDR, 0);
 1328                                         cd_write_reg(cy, CD1400_TDR, 0x83);
 1329                                         CLR(cy->cy_flags, CYF_END_BREAK);
 1330                                 }
 1331                         }
 1332 
 1333                         if (tp->t_outq.c_cc == 0) {
 1334 txdone:
 1335                                 /*
 1336                                  * No data to send or requested to stop.
 1337                                  * Disable transmit interrupt
 1338                                  */
 1339                                 cd_write_reg(cy, CD1400_SRER,
 1340                                     cd_read_reg(cy, CD1400_SRER)
 1341                                     & ~CD1400_SRER_TXRDY);
 1342                                 CLR(cy->cy_flags, CYF_STOP);
 1343                                 CLR(tp->t_state, TS_BUSY);
 1344                         }
 1345 
 1346                         if (tp->t_outq.c_cc <= tp->t_lowat) {
 1347                                 SET(cy->cy_flags, CYF_START);
 1348                                 sc->sc_events = 1;
 1349                         }
 1350 
 1351                         /* terminate service context */
 1352                         cd_write_reg(cy, CD1400_TIR, save_tir & 0x3f);
 1353                         cd_write_reg(cy, CD1400_CAR, save_car);
 1354                         int_serviced = 1;
 1355                 } /* if(tx_service...) */
 1356         } /* for(...all CD1400s on a card) */
 1357 
 1358         /* ensure an edge for next interrupt */
 1359         bus_space_write_1(sc->sc_memt, sc->sc_memh,
 1360             CY_CLEAR_INTR<<sc->sc_bustype, 0);
 1361         return (int_serviced);
 1362 }
 1363 
 1364 /*
 1365  * subroutine to enable CD1400 transmitter
 1366  */
 1367 void
 1368 cy_enable_transmitter(cy)
 1369         struct cy_port *cy;
 1370 {
 1371         int s;
 1372         s = spltty();
 1373         cd_write_reg(cy, CD1400_CAR, cy->cy_port_num & CD1400_CAR_CHAN);
 1374         cd_write_reg(cy, CD1400_SRER, cd_read_reg(cy, CD1400_SRER)
 1375             | CD1400_SRER_TXRDY);
 1376         splx(s);
 1377 }
 1378 
 1379 /*
 1380  * Execute a CD1400 channel command
 1381  */
 1382 void
 1383 cd1400_channel_cmd(cy, cmd)
 1384         struct cy_port *cy;
 1385         int cmd;
 1386 {
 1387         u_int waitcnt = 5 * 8 * 1024; /* approx 5 ms */
 1388 
 1389 #ifdef CY_DEBUG
 1390         printf("c1400_channel_cmd cy 0x%x command 0x%x\n", cy, cmd);
 1391 #endif
 1392 
 1393         /* wait until cd1400 is ready to process a new command */
 1394         while (cd_read_reg(cy, CD1400_CCR) != 0 && waitcnt-- > 0)
 1395                 ;
 1396 
 1397         if (waitcnt == 0)
 1398                 log(LOG_ERR, "cy: channel command timeout\n");
 1399 
 1400         cd_write_reg(cy, CD1400_CCR, cmd);
 1401 }
 1402 
 1403 /*
 1404  * Compute clock option register and baud rate register values
 1405  * for a given speed. Return 0 on success, -1 on failure.
 1406  *
 1407  * The error between requested and actual speed seems
 1408  * to be well within allowed limits (less than 3%)
 1409  * with every speed value between 50 and 150000 bps.
 1410  */
 1411 int
 1412 cy_speed(speed_t speed, int *cor, int *bpr, int cy_clock)
 1413 {
 1414         int c, co, br;
 1415 
 1416         if (speed < 50 || speed > 150000)
 1417                 return (-1);
 1418 
 1419         for (c = 0, co = 8; co <= 2048; co <<= 2, c++) {
 1420                 br = (cy_clock + (co * speed) / 2) / (co * speed);
 1421                 if (br < 0x100) {
 1422                         *bpr = br;
 1423                         *cor = c;
 1424                         return (0);
 1425                 }
 1426         }
 1427 
 1428         return (-1);
 1429 }
 1430 
 1431 #endif /* NCY > 0 */

/* [<][>][^][v][top][bottom][index][help] */