The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/chips/dz_hdw.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* 
    2  * Mach Operating System
    3  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  * 
   23  * any improvements or extensions that they make and grant Carnegie Mellon
   24  * the rights to redistribute these changes.
   25  */
   26 /*
   27  * HISTORY
   28  * $Log:        dz_hdw.c,v $
   29  * Revision 2.19  93/05/30  21:07:06  rvb
   30  *      Added modem CTS/RTS flow control protocol.
   31  *      [93/05/29  09:43:38  af]
   32  * 
   33  * Revision 2.18  93/05/15  19:36:06  mrt
   34  *      machparam.h -> machspl.h
   35  * 
   36  * Revision 2.17  93/05/10  20:07:41  rvb
   37  *      Fixed types.
   38  *      [93/05/06  09:59:28  af]
   39  * 
   40  * Revision 2.16  93/03/26  17:57:56  mrt
   41  *      Removed all uses of minor() and dev_t.
   42  *      [93/03/17            af]
   43  * 
   44  * Revision 2.15  93/02/05  08:18:44  danner
   45  *      splx -> spltty.
   46  *      [93/02/04            danner]
   47  * 
   48  * Revision 2.14  93/01/14  17:15:57  danner
   49  *      Proper spl typing.
   50  *      [92/11/30            af]
   51  * 
   52  * Revision 2.13  92/05/05  10:04:09  danner
   53  *      Adapted to new cons_simple_tint() interface.
   54  *      Also, optimized to invoke the start routine less often.
   55  *      [92/04/14  12:41:44  af]
   56  * 
   57  * Revision 2.12  92/02/19  16:45:42  elf
   58  *      Typo.
   59  *      [92/02/10  17:10:52  af]
   60  * 
   61  * Revision 2.11  91/08/24  11:51:49  af
   62  *      Spl for 3min, padding of regmap here, a lot of code migrated
   63  *      elsewhere to become chip-indep, pseudo-dma is gone.
   64  *      Did not think I changed so much, oops.
   65  *      [91/08/02  02:31:34  af]
   66  * 
   67  * Revision 2.10  91/06/25  20:53:35  rpd
   68  *      Tweaks to make gcc happy.
   69  *      [91/06/25            rpd]
   70  * 
   71  * Revision 2.9  91/06/19  11:47:32  rvb
   72  *      mips->DECSTATION; vax->VAXSTATION
   73  *      [91/06/12  14:01:30  rvb]
   74  * 
   75  *      File moved here from mips/PMAX since it tries to be generic;
   76  *      it is used on the PMAX and the Vax3100.
   77  *      [91/06/04            rvb]
   78  * 
   79  * Revision 2.8  91/05/14  17:21:08  mrt
   80  *      Correcting copyright
   81  * 
   82  * Revision 2.7  91/05/13  06:03:44  af
   83  *      Made use of modem control code optional: patch dz_uses_modem_control
   84  *      if you need it, or call dz_set_modem_control().
   85  *      [91/05/12  16:06:26  af]
   86  * 
   87  * Revision 2.6  91/02/14  14:33:44  mrt
   88  *      In interrupt routine, drop priority as now required.
   89  *      [91/02/12  12:45:12  af]
   90  * 
   91  * Revision 2.5  91/02/05  17:40:35  mrt
   92  *      Added author notices
   93  *      [91/02/04  11:13:03  mrt]
   94  * 
   95  *      Changed to use new Mach copyright
   96  *      [91/02/02  12:10:54  mrt]
   97  * 
   98  * Revision 2.4  91/01/08  16:18:17  rpd
   99  *      Modified dz_param never to use 7bits per char.
  100  *      Now we can use the serial lines even in non-raw mode,
  101  *      which means we can login, for instance.
  102  *      [90/12/31            af]
  103  * 
  104  * Revision 2.3  90/12/05  23:31:02  af
  105  *      Extensive additions for modem support, pmaxen.
  106  *      Still to be tested: autoanswer modems.
  107  *      [90/12/03  23:16:10  af]
  108  * 
  109  * Revision 2.1.1.1  90/11/01  03:37:41  af
  110  *      Created, from the DEC specs:
  111  *      "DECstation 3100 Desktop Workstation Functional Specification"
  112  *      Workstation Systems Engineering, Palo Alto, CA. Aug 28, 1990.
  113  *      and
  114  *      "DECstation 5000/200 KN02 System Module Functional Specification"
  115  *      Workstation Systems Engineering, Palo Alto, CA. Aug 27, 1990.
  116  *      [90/09/03            af]
  117  */
  118 /*
  119  *      File: dz_hdw.c
  120  *      Author: Alessandro Forin, Carnegie Mellon University
  121  *      Date:   9/90
  122  *
  123  *      Hardware-level operations for the DZ Serial Line Driver
  124  */
  125 
  126 #include <dz_.h>
  127 #if     NDZ_ > 0
  128 #include <bm.h>
  129 #include <platforms.h>
  130 
  131 #include <mach_kdb.h>
  132 
  133 #include <machine/machspl.h>            /* spl definitions */
  134 #include <device/io_req.h>
  135 #include <device/tty.h>
  136 
  137 #include <chips/busses.h>
  138 #include <chips/screen_defs.h>
  139 #include <chips/serial_defs.h>
  140 
  141 #include <chips/dz_7085.h>
  142 
  143 
  144 #ifdef  DECSTATION
  145 #include <mips/mips_cpu.h>
  146 #include <mips/PMAX/kn01.h>
  147 #define DZ_REGS_DEFAULT         (vm_offset_t)PHYS_TO_K1SEG(KN01_SYS_DZ)
  148 #define PAD(n)                  char n[6];
  149 #endif  /*DECSTATION*/
  150 
  151 #ifdef  VAXSTATION
  152 #define DZ_REGS_DEFAULT         0
  153 #define wbflush()
  154 #define check_memory(addr,dow)  ((dow) ? wbadaddr(addr,4) : badaddr(addr,4))
  155 #define PAD(n)                  char n[2];
  156 #endif  /*VAXSTATION*/
  157 
  158 #ifndef PAD
  159 #define PAD(n)
  160 #endif
  161 
  162 typedef struct {
  163         volatile unsigned short dz_csr;         /* Control and Status */
  164                                                                 PAD(pad0)
  165         volatile unsigned short dz_rbuf;        /* Rcv buffer (RONLY) */
  166                                                                 PAD(pad1)
  167         volatile unsigned short dz_tcr;         /* Xmt control (R/W)*/
  168                                                                 PAD(pad2)
  169         volatile unsigned short dz_tbuf;        /* Xmt buffer (WONLY)*/
  170 #       define                  dz_lpr dz_rbuf  /* Line parameters (WONLY)*/
  171 #       define                  dz_msr dz_tbuf  /* Modem status (RONLY)*/
  172                                                                 PAD(pad3)
  173 } dz_padded_regmap_t;
  174 
  175 
  176 /* this is ok both for rcv (char) and xmt (csr) */
  177 #define LINEOF(x)       (((x) >> 8) & 0x3)
  178 
  179 /*
  180  * Driver status
  181  */
  182 struct dz7085_softc {
  183         dz_padded_regmap_t      *regs;
  184         unsigned short  breaks;
  185         unsigned short  fake;   /* missing rs232 bits */
  186         int             polling_mode;
  187         unsigned short  prev_msr;
  188         char            softCAR;
  189 } dz7085_softc_data[NDZ_];
  190 
  191 typedef struct dz7085_softc *dz7085_softc_t;
  192 
  193 dz7085_softc_t  dz7085_softc[NDZ_];
  194 
  195 static void             check_car();
  196 static void             check_ring();
  197 
  198 dz7085_softCAR(unit, line, on)
  199 {
  200         if (on)
  201                 dz7085_softc[unit]->softCAR |= 1<<line;
  202         else
  203                 dz7085_softc[unit]->softCAR &= ~(1 << line);
  204 }
  205 
  206 static
  207 short   dz7085_speeds[] =
  208         { 0, DZ_LPAR_50, DZ_LPAR_75, DZ_LPAR_110, DZ_LPAR_134_5, DZ_LPAR_150,
  209           0, DZ_LPAR_300, DZ_LPAR_600, DZ_LPAR_1200, DZ_LPAR_1800, DZ_LPAR_2400,
  210           DZ_LPAR_4800, DZ_LPAR_9600, DZ_LPAR_MAX_SPEED, 0 };
  211 
  212 
  213 /*
  214  * Definition of the driver for the auto-configuration program.
  215  */
  216 
  217 int     dz7085_probe(), dz7085_intr();
  218 static void     dz7085_attach();
  219 
  220 vm_offset_t     dz7085_std[NDZ_] = { DZ_REGS_DEFAULT, };
  221 struct  bus_device *dz7085_info[NDZ_];
  222 struct  bus_driver dz_driver = 
  223         { dz7085_probe, 0, dz7085_attach, 0, dz7085_std, "dz", dz7085_info,};
  224 
  225 /*
  226  * Adapt/Probe/Attach functions
  227  */
  228 
  229 static boolean_t        dz7085_full_modem = FALSE;
  230 boolean_t               dz7085_uses_modem_control = FALSE;/* patch this with adb */
  231 
  232 set_dz_address( unit, regs, has_modem)
  233         vm_offset_t             regs;
  234         boolean_t       has_modem;
  235 {
  236         extern int      dz7085_probe(), dz7085_param(), dz7085_start(),
  237                         dz7085_putc(), dz7085_getc(),
  238                         dz7085_pollc(), dz7085_mctl(), dz7085_softCAR();
  239 
  240         dz7085_std[unit] = regs;
  241         dz7085_full_modem = has_modem & dz7085_uses_modem_control;
  242 
  243         /* Do this here */
  244         console_probe           = dz7085_probe;
  245         console_param           = dz7085_param;
  246         console_start           = dz7085_start;
  247         console_putc            = dz7085_putc;
  248         console_getc            = dz7085_getc;
  249         console_pollc           = dz7085_pollc;
  250         console_mctl            = dz7085_mctl;
  251         console_softCAR         = dz7085_softCAR;
  252 
  253 }
  254 
  255 dz7085_probe( xxx, ui)
  256         struct bus_device *ui;
  257 {
  258         int             unit = ui->unit;
  259         dz7085_softc_t      sc;
  260         register int    cntr;
  261         register dz_padded_regmap_t     *regs;
  262 
  263         static int probed_once = 0;
  264 
  265         regs = (dz_padded_regmap_t *)dz7085_std[unit];  /* like the old days! */
  266         if (regs == 0)
  267                 return 0;
  268         /*
  269          * If this is not there we are toast 
  270          */
  271         if (check_memory(regs, 0))
  272                 return 0;
  273 
  274         if (probed_once++)
  275                 return 1;
  276 
  277         sc = &dz7085_softc_data[unit];
  278         dz7085_softc[unit] = sc;
  279         sc->regs = regs;
  280 
  281         for (cntr = unit*NDZ_LINE; cntr < NDZ_LINE*(unit+1); cntr++) {
  282                 console_tty[cntr]->t_addr = (char*)regs;
  283                 console_tty[cntr]->t_state |= TS_MIN;
  284         }
  285 
  286         /* pmaxen et al. lack many modem bits */
  287         dz7085_set_modem_control(sc, dz7085_full_modem);
  288 
  289         regs->dz_tcr = 0;/* disable all lines, drop RTS,DTR */
  290         return 1;
  291 }
  292 
  293 boolean_t dz7085_timer_started = FALSE;
  294 
  295 static void
  296 dz7085_attach(ui)
  297         register struct bus_device *ui;
  298 {
  299         int unit = ui->unit;
  300         extern dz7085_scan();
  301         extern int tty_inq_size;
  302         int i;
  303 
  304         /* We only have 4 ttys, but always at 9600
  305          * Give em a lot of room
  306          */
  307         tty_inq_size = 2048;
  308         for (i = 0; i < (NDZ_*NDZ_LINE); i++)
  309                 ttychars(console_tty[i]);
  310 
  311         if (!dz7085_timer_started) {
  312                 dz7085_timer_started = TRUE;
  313                 dz7085_scan();
  314         }
  315 
  316 #if     NBM > 0
  317         if (SCREEN_ISA_CONSOLE()) {
  318                 printf("\n sl0: "); lk201_attach(0, unit);
  319                 printf("\n sl1: "); mouse_attach(0, unit);
  320                 printf("\n sl2: \n sl3: ");
  321                 if (rcline == 3) printf("( rconsole )");
  322         } else {
  323 #endif  /*NBM > 0*/
  324                 printf("\n sl0:\n sl1:\n sl2:\n sl3: ( alternate console )");
  325 #if     NBM > 0
  326         }
  327 #endif
  328 }
  329 
  330 /*
  331  * Would you like to make a phone call ?
  332  */
  333 dz7085_set_modem_control(sc, on)
  334         dz7085_softc_t      sc;
  335         boolean_t       on;
  336 {
  337         if (on)
  338                 /* your problem if the hardware then is broke */
  339                 sc->fake = 0;
  340         else
  341                 sc->fake = DZ_MSR_CTS3|DZ_MSR_DSR3|DZ_MSR_CD3|
  342                            DZ_MSR_CTS2|DZ_MSR_CD2;
  343 }
  344 
  345 /*
  346  * Polled I/O (debugger)
  347  */
  348 dz7085_pollc(unit, on)
  349         boolean_t               on;
  350 {
  351         dz7085_softc_t          sc = dz7085_softc[unit];
  352 
  353         if (on) {
  354                 sc->polling_mode++;
  355 #if     NBM > 0
  356                 screen_on_off(unit, TRUE);
  357 #endif  NBM > 0
  358         } else
  359                 sc->polling_mode--;
  360 }
  361 
  362 /*
  363  * Interrupt routine
  364  */
  365 dz_intr(unit,spllevel)
  366         spl_t   spllevel;
  367 {
  368         dz7085_softc_t          sc = dz7085_softc[unit];
  369         register dz_padded_regmap_t     *regs = sc->regs;
  370         register short          csr;
  371 
  372         csr = regs->dz_csr;
  373 
  374         if (csr & DZ_CSR_TRDY) {
  375                 register int             c;
  376 
  377                 c = cons_simple_tint(unit*NDZ_LINE + LINEOF(csr), FALSE);
  378                 if (c == -1) {
  379                         /* no more data for this line */
  380                         regs->dz_tcr &= ~(1 << LINEOF(csr));
  381                         c = cons_simple_tint(unit*NDZ_LINE + LINEOF(csr), TRUE);
  382                         /* because funny race possible ifnot */
  383                 }
  384                 if (c != -1) {
  385                         regs->dz_tbuf = (c & 0xff) | sc->breaks;
  386                         /* and leave it enabled */
  387                 }
  388         }
  389         if (sc->polling_mode)
  390                 return;
  391 
  392         while (regs->dz_csr & DZ_CSR_RDONE) {
  393                 short           c = regs->dz_rbuf;
  394                 spl_t           oldspl;
  395 
  396 #ifdef  DECSTATION
  397                 oldspl = splhigh();
  398                 splx(spllevel);
  399 #endif  /*DECSTATION*/
  400                 cons_simple_rint(unit*NDZ_LINE+LINEOF(c), LINEOF(c),
  401                                 c&0xff, c&0xff00);
  402 #ifdef  DECSTATION
  403                 splx(oldspl);
  404 #endif  /*DECSTATION*/
  405         }
  406 }
  407 
  408 /*
  409  * Start transmission on a line
  410  */
  411 dz7085_start(tp)
  412         struct tty *tp;
  413 {
  414         register dz_padded_regmap_t     *regs;
  415         register int            line;
  416 
  417         line = tp->t_dev;
  418 
  419         regs = (dz_padded_regmap_t*)tp->t_addr;
  420         regs->dz_tcr |= (1<<(line&3));
  421 
  422         /* no, we do not need a char out to interrupt */
  423 }
  424 
  425 /*
  426  * Get a char from a specific DZ line
  427  */
  428 dz7085_getc( unit, line, wait, raw )
  429         boolean_t       wait;
  430         boolean_t       raw;
  431 {
  432         dz7085_softc_t      sc = dz7085_softc[unit];
  433         spl_t               s = spltty();
  434         register dz_padded_regmap_t *regs = sc->regs;
  435         unsigned short  c;
  436         int             rl;
  437 
  438 again:
  439         /*
  440          * wait till something in silo 
  441          */
  442         while ((regs->dz_csr & DZ_CSR_RDONE) == 0 && wait)
  443                 delay(10);
  444         c = regs->dz_rbuf;
  445 
  446         /*
  447          * check if right line. For keyboard, rconsole is ok too 
  448          */
  449         rl = LINEOF(c);
  450         if (wait && (line != rl) &&
  451             !((line == DZ_LINE_KEYBOARD) && rcline == rl))
  452                 goto again;
  453         /*
  454          * bad chars not ok 
  455          */
  456         if ((c & (DZ_RBUF_PERR | DZ_RBUF_OERR | DZ_RBUF_FERR)) && wait)
  457                 goto again;
  458 
  459         splx(s);
  460 
  461         /*
  462          * if nothing found return -1 
  463          */
  464         if ( ! (c & DZ_RBUF_VALID))
  465                 return -1;
  466 
  467 #if     NBM > 0
  468         if ((rl == DZ_LINE_KEYBOARD) && !raw && SCREEN_ISA_CONSOLE())
  469                 return lk201_rint(SCREEN_CONS_UNIT(), c, wait, sc->polling_mode);
  470         else
  471 #endif  NBM > 0
  472                 return c & DZ_RBUF_CHAR;
  473 }
  474 
  475 /*
  476  * Put a char on a specific DZ line
  477  */
  478 dz7085_putc( unit, line, c )
  479 {
  480         dz7085_softc_t      sc = dz7085_softc[unit];
  481         register dz_padded_regmap_t *regs = sc->regs;
  482         spl_t               s = spltty();
  483 
  484         /*
  485          * do not change the break status of other lines 
  486          */
  487         c = (c & 0xff) | sc->breaks;
  488 
  489         /*
  490          * Xmit line info only valid if TRDY,
  491          * but never TRDY if no xmit enabled
  492          */
  493         if ((regs->dz_tcr & DZ_TCR_LNENB) == 0)
  494                 goto select_it;
  495 
  496         while ((regs->dz_csr & DZ_CSR_TRDY) == 0)
  497                 delay(100);
  498 
  499         /*
  500          * see if by any chance we are already on the right line 
  501          */
  502         if (LINEOF(regs->dz_csr) == line)
  503                 regs->dz_tbuf = c;
  504         else {
  505                 unsigned short tcr;
  506 select_it:
  507                 tcr = regs->dz_tcr;
  508                 regs->dz_tcr = (1 << line) | (tcr & 0xff00);
  509                 wbflush();
  510 
  511                 do
  512                         delay(2);
  513                 while ((regs->dz_csr & DZ_CSR_TRDY) == 0 ||
  514                        (LINEOF(regs->dz_csr) != line));
  515 
  516                 regs->dz_tbuf = c;
  517                 wbflush();
  518 
  519                 /* restore previous settings */
  520                 regs->dz_tcr = tcr;
  521         }
  522 
  523         splx(s);
  524 }
  525 
  526 
  527 dz7085_param(tp, line)
  528         register struct tty     *tp;
  529         register int            line;
  530 {
  531         register dz_padded_regmap_t *regs;
  532         register int lpr;
  533  
  534         line = tp->t_dev;
  535         regs = dz7085_softc[line/NDZ_LINE]->regs;
  536 
  537         /*
  538          * Do not let user fool around with kbd&mouse
  539          */
  540 #if     NBM > 0
  541         if (screen_captures(line)) {
  542                 tp->t_ispeed = tp->t_ospeed = B4800;
  543                 tp->t_flags |= TF_LITOUT;
  544         }
  545 #endif  NBM > 0
  546         regs->dz_csr = DZ_CSR_MSE|DZ_CSR_RIE|DZ_CSR_TIE;
  547         if (tp->t_ispeed == 0) {
  548                 (void) (*console_mctl)(tp->t_dev, TM_HUP, DMSET);       /* hang up line */
  549                 return;
  550         }
  551 /* 19200/38400 here */
  552         lpr = dz7085_speeds[tp->t_ispeed] | (line&DZ_LPAR_LINE) | DZ_LPAR_ENABLE;
  553         lpr |= DZ_LPAR_8BITS;
  554 
  555         if ((tp->t_flags & (TF_ODDP|TF_EVENP)) == TF_ODDP)
  556                 lpr |= DZ_LPAR_ODD_PAR;
  557 
  558         if (tp->t_ispeed == B110)
  559                 lpr |= DZ_LPAR_STOP;
  560         regs->dz_lpr = lpr;
  561 }
  562  
  563 /*
  564  * This is a total mess: not only are bits spread out in
  565  * various registers, but we have to fake some for pmaxen.
  566  */
  567 dz7085_mctl(dev, bits, how)
  568         int dev;
  569         int bits, how;
  570 {
  571         register dz_padded_regmap_t *regs;
  572         register int unit;
  573         register int tcr, msr, brk, n_tcr, n_brk;
  574         int b;
  575         spl_t s;
  576         dz7085_softc_t      sc;
  577 
  578         unit = dev;
  579 
  580         /* no modem support on lines 0 & 1 */
  581 /* XXX break on 0&1 */
  582         if ((unit & 2) == 0)
  583                 return TM_LE|TM_DTR|TM_CTS|TM_CAR|TM_DSR;
  584 
  585         b = 1 ^ (unit & 1);     /* line 2 ? */
  586         
  587         sc = dz7085_softc[unit>>2];
  588         regs = sc->regs;
  589         s = spltty();
  590 
  591         tcr = ((regs->dz_tcr | (sc->fake>>4)) & 0xf00) >> (8 + b*2);
  592         brk = (sc->breaks >> (8 + (unit&3))) & 1;       /* THE break bit */
  593 
  594         n_tcr = (bits & (TM_RTS|TM_DTR)) >> 1;
  595         n_brk = (bits & TM_BRK) >> 9;
  596 
  597         /* break transitions, must 'send' a char out */
  598         bits = (brk ^ n_brk) & 1;
  599 
  600         switch (how) {
  601         case DMSET:
  602                 tcr = n_tcr;
  603                 brk = n_brk;
  604                 break;
  605 
  606         case DMBIS:
  607                 tcr |= n_tcr;
  608                 brk |= n_brk;
  609                 break;
  610 
  611         case DMBIC:
  612                 tcr &= ~n_tcr;
  613                 brk = 0;
  614                 break;
  615 
  616         case DMGET:
  617                 msr = ((regs->dz_msr|sc->fake) & 0xf0f) >> (b*8);
  618                 (void) splx(s);
  619                 return  (tcr<<1)|/* DTR, RTS */
  620                         ((msr&1)<<5)|/* CTS */
  621                         ((msr&2)<<7)|/* DSR */
  622                         ((msr&0xc)<<4)|/* CD, RNG */
  623                         (brk << 9)|/* BRK */
  624                         TM_LE;
  625         }
  626         n_tcr = (regs->dz_tcr & ~(3 << (8 + b*2))) |
  627                 (tcr << (8 + b*2));
  628 
  629         regs->dz_tcr = n_tcr;
  630         sc->fake = (sc->fake & 0xf0f) | (n_tcr<<4&0xf000);
  631 
  632         sc->breaks = (sc->breaks & ~(1 << (8 + (unit&3)))) |
  633                     (brk << (8 + (unit&3)));
  634         if(bits) (*console_putc)( unit>>2, unit&3, 0);/* force break, now */
  635         (void) splx(s);
  636         return 0;/* useless to compute it */
  637 }
  638 
  639 /*
  640  * Periodically look at the CD signals:
  641  * they do not generate interrupts.
  642  */
  643 dz7085_scan()
  644 {
  645         register i;
  646         register dz_padded_regmap_t *regs;
  647         register msr;
  648         register struct tty *tp;
  649  
  650         for (i = 0; i < NDZ_; i++) {
  651                 dz7085_softc_t      sc = dz7085_softc[i];
  652                 register int    temp;
  653 
  654                 if (sc == 0)
  655                         continue;
  656                 regs = sc->regs;
  657 
  658                 tp = console_tty[i * NDZ_LINE];
  659 
  660                 msr = regs->dz_msr | (sc->fake & 0xf0f);
  661                 if (temp = sc->softCAR) {
  662                         if (temp & 0x4)
  663                                 msr |= DZ_MSR_CD2 | DZ_MSR_CTS2;
  664                         if (temp & 0x8)
  665                                 msr |= DZ_MSR_CD3 | DZ_MSR_CTS3;
  666                 }
  667 
  668                 /* Lines 0 and 1 have carrier on by definition */
  669                 /* [horrid casts cuz compiler stupid] */
  670                 check_car((char*)tp + 0*sizeof(struct tty), 1);
  671                 check_car((char*)tp + 1*sizeof(struct tty), 1);
  672                 check_car((char*)tp + 2*sizeof(struct tty), msr & DZ_MSR_CD2);
  673                 check_car((char*)tp + 3*sizeof(struct tty), msr & DZ_MSR_CD3);
  674 
  675                 /* nothing else to do if no msr transitions */
  676                 if ((temp = sc->prev_msr) == msr)
  677                         continue;
  678                 else
  679                         sc->prev_msr = msr;
  680 
  681                 /* see if we have an incoming call */
  682 #define RING    (DZ_MSR_RI2|DZ_MSR_RI3)
  683                 if ((msr & RING) != (temp & RING)) {
  684 /*printf("%s %x->%x\n", "ET Phone RI", temp & RING, msr & RING);*/
  685                         check_ring((char*)tp + 2*sizeof(struct tty),
  686                                 msr & DZ_MSR_RI2, temp & DZ_MSR_RI2);
  687                         check_ring((char*)tp + 3*sizeof(struct tty),
  688                                 msr & DZ_MSR_RI3, temp & DZ_MSR_RI3);
  689                 }
  690 #undef RING
  691                 /* see if we must do flow-control */
  692                 if ((msr ^ temp) & DZ_MSR_CTS2) {
  693                         tty_cts((char*)tp + 2*sizeof(struct tty),
  694                                 msr & DZ_MSR_CTS2);
  695                 }
  696                 if ((msr ^ temp) & DZ_MSR_CTS3) {
  697                         tty_cts((char*)tp + 3*sizeof(struct tty),
  698                                 msr & DZ_MSR_CTS3);
  699                 }
  700         }
  701         timeout(dz7085_scan, (vm_offset_t)0, 2*hz);
  702 }
  703 
  704 static dz7085_hup(tp)
  705         register struct tty *tp;
  706 {
  707         (*console_mctl)(tp->t_dev, TM_DTR, DMBIC);
  708 }
  709 
  710 static void check_car(tp, car)
  711         register struct tty *tp;
  712 {
  713         if (car) {
  714                 /* cancel modem timeout if need to */
  715                 if (car & (DZ_MSR_CD2|DZ_MSR_CD3))
  716                         untimeout(dz7085_hup, (vm_offset_t)tp);
  717 
  718                 /* I think this belongs in the MI code */
  719                 if (tp->t_state & TS_WOPEN)
  720                         tp->t_state |= TS_ISOPEN;
  721                 /* carrier present */
  722                 if ((tp->t_state & TS_CARR_ON) == 0)
  723                         (void)ttymodem(tp, 1);
  724         } else if ((tp->t_state&TS_CARR_ON) && ttymodem(tp, 0) == 0)
  725                 (*console_mctl)( tp->t_dev, TM_DTR, DMBIC);
  726 }
  727 
  728 int     dz7085_ring_timeout     = 60;   /* seconds, patchable */
  729 
  730 static void check_ring(tp, ring, oring)
  731         register struct tty *tp;
  732 {
  733         if (ring == oring)
  734                 return;
  735         if (ring) {
  736                 (*console_mctl)( tp->t_dev, TM_DTR, DMBIS);
  737                 /* give it ample time to find the right carrier */
  738                 timeout(dz7085_hup, (vm_offset_t)tp, dz7085_ring_timeout*hz);
  739         }
  740 }
  741 #endif  NDZ_ > 0

Cache object: 683d80a614734cf09c445252e28ae9ec


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.