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

Cache object: 2ef425a4b66f42c1ee67634e3208c32a


[ 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.