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/device/chario.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-1988 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:        chario.c,v $
   29  * Revision 2.27  93/11/17  16:29:34  dbg
   30  *      Added include of kern/time_out.h.
   31  *      [93/06/04            dbg]
   32  * 
   33  * Revision 2.26  93/08/10  15:10:24  mrt
   34  *      Added test to check that buffer is large enough to hold data
   35  *      returned by tty_get_status. Fix by Tero Kivinen (kivinen) at
   36  *      Helsinki University of Technology. This code was added in
   37  *      Rev 2.20 and flushed by misktake in Rev 24.
   38  *      [93/08/09            mrt]
   39  * 
   40  * Revision 2.25  93/08/03  12:31:04  mrt
   41  *      Removed the check for success on putc in ttyinput. 
   42  *      We want to wakeup everyone on the delayed queue, regardless
   43  *      of how the putc turned out.
   44  *      Fix by bsy and af.
   45  *      [93/08/03            mrt]
   46  * 
   47  * Revision 2.24  93/05/30  21:07:50  rvb
   48  *      Added calls for modem control operations. Pdma code on by default.
   49  *      Added ttyinput_many and tty_cts. Lint.
   50  *      [93/05/29  09:50:55  af]
   51  * 
   52  * Revision 2.23  93/05/17  20:11:55  rvb
   53  *      Flush some debugging for AF
   54  * 
   55  * Revision 2.22  93/05/15  18:52:43  mrt
   56  *      machparam.h -> machspl.h
   57  * 
   58  * Revision 2.21  93/05/10  21:18:05  rvb
   59  *      Fixed pdma stuff.
   60  *      [93/05/06  11:07:39  af]
   61  * 
   62  * Revision 2.20  93/05/10  17:46:00  rvb
   63  *      Added test to check that buffer is large enough to hold data
   64  *      returned by tty_get_status.
   65  *      [93/04/20            kivinen]
   66  * 
   67  * Revision 2.19  93/03/18  10:37:17  mrt
   68  *      Missed a label.
   69  *      [93/03/18  01:04:14  af]
   70  * 
   71  *      Compressed code here and there.
   72  *      [93/03/17            af]
   73  * 
   74  * Revision 2.18  93/02/01  09:46:22  danner
   75  *      Extend buffering down to 300 baud.
   76  *      [93/01/27            danner]
   77  * 
   78  *      Refined pdma support (feedback from rvb & af).
   79  *      [93/01/27            danner]
   80  * 
   81  * Revision 2.17  93/01/14  17:26:27  danner
   82  *      Proper spl typing. 64bit safe. Bumped up tty_inq_size.
   83  *      [92/11/30            af]
   84  * 
   85  *      Added function prototypes.  Fixed documentation.
   86  *      Removed tty_queueempty and ttyoutput.
   87  *      [92/11/17            dbg]
   88  * 
   89  * Revision 2.16  92/08/03  17:32:48  jfriedl
   90  *      removed silly prototypes
   91  *      [92/08/02            jfriedl]
   92  * 
   93  * Revision 2.15  92/05/21  17:08:37  jfriedl
   94  *      Added void to fcns that still needed it.
   95  *      Made CHAR args to ttyinput() and ttyoutput() UNSIGNED.
   96  *      [92/05/16            jfriedl]
   97  * 
   98  * Revision 2.14  92/05/05  10:46:10  danner
   99  *      Added (optional) delayed wakeup of receiver until
  100  *      a minimum of chars present, or timeout.
  101  *      [92/05/04  11:29:43  af]
  102  * 
  103  * Revision 2.13  91/09/12  16:36:51  bohman
  104  *      Added missing clear of TS_TTSTOP in char_write().
  105  *      TS_INIT belongs in t_state, not t_flags.
  106  *      [91/09/11  17:04:18  bohman]
  107  * 
  108  * Revision 2.12  91/08/28  11:11:08  jsb
  109  *      Fixed char_write to check vm_map_copyout's return code.
  110  *      [91/08/03            rpd]
  111  * 
  112  * Revision 2.11  91/08/24  11:55:34  af
  113  *      Spl definitions.
  114  *      [91/08/02  02:44:21  af]
  115  * 
  116  * Revision 2.10  91/05/14  15:39:09  mrt
  117  *      Correcting copyright
  118  * 
  119  * Revision 2.9  91/02/05  17:07:55  mrt
  120  *      Changed to new Mach copyright
  121  *      [91/01/31  17:26:20  mrt]
  122  * 
  123  * Revision 2.8  90/08/27  21:54:21  dbg
  124  *      Fixed type declaration for char_open.
  125  *      [90/07/16            dbg]
  126  * 
  127  *      Added call to cb_alloc in ttychars.
  128  *      [90/07/09            dbg]
  129  * 
  130  * Revision 2.7  90/06/02  14:47:02  rpd
  131  *      Updated for new IPC.  Purged MACH_XP_FPD.
  132  *      [90/03/26  21:42:42  rpd]
  133  * 
  134  * Revision 2.6  90/01/11  11:41:39  dbg
  135  *      Fix test on 'i' (clist exhausted) in char_write.
  136  *      Document what operations need locking, and which must be
  137  *      serialized if the device driver only runs on one CPU.
  138  *      [89/11/30            dbg]
  139  * 
  140  * Revision 2.5  89/11/29  14:08:50  af
  141  *      char_write wasn't calling b_to_q() with the right char count.
  142  *      [89/11/11            af]
  143  *      Marked tty as initialized in ttychars.
  144  *      [89/11/03  16:57:39  af]
  145  * 
  146  * Revision 2.4  89/09/08  11:23:01  dbg
  147  *      Add in-band write check to char_write.
  148  *      [89/08/30            dbg]
  149  * 
  150  *      Make char_write copy data directly from user instead of wiring
  151  *      down data buffer first.
  152  *      [89/08/24            dbg]
  153  * 
  154  *      Convert to run in kernel task.
  155  *      [89/07/27            dbg]
  156  * 
  157  * Revision 2.3  89/08/31  16:17:20  rwd
  158  *      Don't assume adequate spl when inserting/deleting ior's from
  159  *      delay queues.
  160  *      [89/08/31            rwd]
  161  * 
  162  * Revision 2.2  89/08/05  16:04:35  rwd
  163  *      Added tty_queueempty for sun console input polling.
  164  *      Added ttyoutput for sundev/kbd.c.  Allow inband data.
  165  *      [89/06/02            rwd]
  166  * 
  167  * 18-May-89  David Golub (dbg) at Carnegie-Mellon University
  168  *      Check for uninitialized TTY queues in close/port_death.
  169  *
  170  * 12-Apr-89  David Golub (dbg) at Carnegie-Mellon University
  171  *      Added port_death routines.
  172  *
  173  * 24-Aug-88  David Golub (dbg) at Carnegie-Mellon University
  174  *      Created.
  175  *
  176  */
  177 /*
  178  *      Author: David B. Golub, Carnegie Mellon University
  179  *      Date:   8/88
  180  *
  181  *      TTY io.
  182  *      Compatibility with old TTY device drivers.
  183  */
  184 
  185 #include <mach/kern_return.h>
  186 #include <mach/mig_errors.h>
  187 #include <mach/vm_param.h>
  188 
  189 #include <ipc/ipc_port.h>
  190 
  191 #include <kern/lock.h>
  192 #include <kern/queue.h>
  193 #include <kern/time_out.h>
  194 
  195 #include <vm/vm_map.h>
  196 #include <vm/vm_kern.h>
  197 #include <vm/vm_user.h>
  198 
  199 #include <device/device_types.h>
  200 #include <device/io_req.h>
  201 #include <device/ds_routines.h>
  202 #include <device/device_reply.h>
  203 
  204 #include <device/tty.h>
  205 
  206 #include <machine/machspl.h>    /* for spl */
  207 
  208 short   tthiwat[16] =
  209    { 100,100,100,100,100,100,100,200,200,400,400,400,650,650,1300,2000 };
  210 short   ttlowat[16] =
  211    {  30, 30, 30, 30, 30, 30, 30, 50, 50,120,120,120,125,125, 125, 125 };
  212 
  213 /*
  214  * forward declarations
  215  */
  216 void    queue_delayed_reply(
  217         queue_t, io_req_t, boolean_t (*)(io_req_t));
  218 void    tty_output(struct tty *);
  219 void    tty_flush(struct tty *, int);
  220 boolean_t char_open_done(io_req_t);
  221 boolean_t char_read_done(io_req_t);
  222 boolean_t char_write_done(io_req_t);
  223 
  224 /*
  225  * Fake 'line discipline' switch for the benefit of old code
  226  * that wants to call through it.
  227  */
  228 struct ldisc_switch     linesw[] = {
  229         {
  230             char_read,
  231             char_write,
  232             ttyinput,
  233             ttymodem,
  234             tty_output
  235         }
  236 };
  237 
  238 /*
  239  * Sizes for input and output circular buffers.
  240  */
  241 int     tty_inq_size = 4096;    /* big nuf */
  242 int     tty_outq_size = 256;    /* XXX */
  243 int     pdma_default = 1;       /* turn pseudo dma on by default */
  244 
  245 /*
  246  * compute pseudo-dma tables 
  247  */
  248 
  249 int pdma_timeouts[NSPEEDS]; /* how many ticks in timeout */
  250 int pdma_water_mark[NSPEEDS];
  251 
  252 
  253 void chario_init(void)
  254 {
  255   /* the basic idea with the timeouts is two allow enough
  256      time for a character to show up if data is coming in at full data rate
  257      plus a little slack. 2 ticks is considered slack
  258      Below 300 baud we just glob a character at a time */
  259 #define _PR(x) ((hz/x) + 2)
  260 
  261   int i;
  262 
  263   for (i = B0; i < B300; i++)
  264     pdma_timeouts[i] = 0;
  265   
  266   pdma_timeouts[B300] = _PR(30);
  267   pdma_timeouts[B600] = _PR(60);
  268   pdma_timeouts[B1200] = _PR(120);
  269   pdma_timeouts[B1800] = _PR(180);
  270   pdma_timeouts[B2400] = _PR(240);
  271   pdma_timeouts[B4800] = _PR(480);
  272   pdma_timeouts[B9600] = _PR(960);
  273   pdma_timeouts[EXTA]  = _PR(1440); /* >14400 baud */
  274   pdma_timeouts[EXTB]  = _PR(1920); /* >19200 baud */
  275 
  276   for (i = B0; i < B300; i++)
  277     pdma_water_mark[i] = 0;
  278 
  279   /* for the slow speeds, we try to buffer 0.02 of the baud rate
  280      (20% of the character rate). For the faster lines,
  281      we try to buffer 1/2 the input queue size */
  282 
  283 #undef _PR
  284 #define _PR(x) (0.20 * x)
  285 
  286   pdma_water_mark[B300] = _PR(120);
  287   pdma_water_mark[B600] = _PR(120);
  288   pdma_water_mark[B1200] = _PR(120);
  289   pdma_water_mark[B1800] = _PR(180);
  290   pdma_water_mark[B2400] = _PR(240);
  291   pdma_water_mark[B4800] = _PR(480);
  292   i = tty_inq_size/2;
  293   pdma_water_mark[B9600] = i;
  294   pdma_water_mark[EXTA]  = i; /* >14400 baud */
  295   pdma_water_mark[EXTB]  = i; /* >19200 baud */
  296 
  297   return; 
  298 }
  299 
  300 /*
  301  * Open TTY, waiting for CARR_ON.
  302  * No locks may be held.
  303  * May run on any CPU.
  304  */
  305 io_return_t char_open(
  306         int             dev,
  307         struct tty *    tp,
  308         dev_mode_t      mode,
  309         io_req_t        ior)
  310 {
  311         spl_t   s;
  312         io_return_t     rc = D_SUCCESS;
  313 
  314         s = spltty();
  315         simple_lock(&tp->t_lock);
  316 
  317         tp->t_dev = dev;
  318 
  319         if (tp->t_mctl)
  320                 (*tp->t_mctl)(tp, TM_DTR, DMSET);
  321 
  322         if (pdma_default)
  323           tp->t_state |= TS_MIN;
  324 
  325         if ((tp->t_state & TS_CARR_ON) == 0) {
  326             /*
  327              * No carrier.
  328              */
  329             if (mode & D_NODELAY) {
  330                 tp->t_state |= TS_ONDELAY;
  331             }
  332             else {
  333                 /*
  334                  * Don`t return from open until carrier detected.
  335                  */
  336                 tp->t_state |= TS_WOPEN;
  337 
  338                 ior->io_dev_ptr = (char *)tp;
  339 
  340                 queue_delayed_reply(&tp->t_delayed_open, ior, char_open_done);
  341                 rc = D_IO_QUEUED;
  342                 goto out;
  343             }
  344         }
  345         tp->t_state |= TS_ISOPEN;
  346         if (tp->t_mctl)
  347                 (*tp->t_mctl)(tp, TM_RTS, DMBIS);
  348 out:
  349         simple_unlock(&tp->t_lock);
  350         splx(s);
  351         return rc;
  352 }
  353 
  354 /*
  355  * Retry wait for CARR_ON for open.
  356  * No locks may be held.
  357  * May run on any CPU.
  358  */
  359 boolean_t char_open_done(
  360         io_req_t        ior)
  361 {
  362         register struct tty *tp = (struct tty *)ior->io_dev_ptr;
  363         spl_t s = spltty();
  364 
  365         simple_lock(&tp->t_lock);
  366         if ((tp->t_state & TS_ISOPEN) == 0) {
  367             queue_delayed_reply(&tp->t_delayed_open, ior, char_open_done);
  368             simple_unlock(&tp->t_lock);
  369             splx(s);
  370             return FALSE;
  371         }
  372 
  373         tp->t_state |= TS_ISOPEN;
  374         tp->t_state &= ~TS_WOPEN;
  375 
  376         if (tp->t_mctl)
  377                 (*tp->t_mctl)(tp, TM_RTS, DMBIS);
  378 
  379         simple_unlock(&tp->t_lock);
  380         splx(s);
  381 
  382         ior->io_error = D_SUCCESS;
  383         (void) ds_open_done(ior);
  384         return TRUE;
  385 }
  386 
  387 boolean_t tty_close_open_reply(
  388         io_req_t        ior)
  389 {
  390         ior->io_error = D_DEVICE_DOWN;
  391         (void) ds_open_done(ior);
  392         return TRUE;
  393 }
  394 
  395 /*
  396  * Write to TTY.
  397  * No locks may be held.
  398  * Calls device start routine; must already be on master if
  399  * device needs to run on master.
  400  */
  401 io_return_t char_write(
  402         register struct tty *   tp,
  403         register io_req_t       ior)
  404 {
  405         spl_t           s;
  406         register int    count;
  407         register char   *data;
  408         vm_offset_t     addr;
  409         io_return_t     rc = D_SUCCESS;
  410 
  411         data  = ior->io_data;
  412         count = ior->io_count;
  413         if (count == 0)
  414             return rc;
  415 
  416         if (!(ior->io_op & IO_INBAND)) {
  417             /*
  418              * Copy out-of-line data into kernel address space.
  419              * Since data is copied as page list, it will be
  420              * accessible.
  421              */
  422             vm_map_copy_t copy = (vm_map_copy_t) data;
  423             kern_return_t kr;
  424 
  425             kr = vm_map_copyout(device_io_map, &addr, copy);
  426             if (kr != KERN_SUCCESS)
  427                 return kr;
  428             data = (char *) addr;
  429         }
  430 
  431         /*
  432          * Check for tty operating.
  433          */
  434         s = spltty();
  435         simple_lock(&tp->t_lock);
  436 
  437         if ((tp->t_state & TS_CARR_ON) == 0) {
  438 
  439             if ((tp->t_state & TS_ONDELAY) == 0) {
  440                 /*
  441                  * No delayed writes - tell caller that device is down
  442                  */
  443                 rc = D_IO_ERROR;
  444                 goto out;
  445             }
  446 
  447             if (ior->io_mode & D_NOWAIT) {
  448                 rc = D_WOULD_BLOCK;
  449                 goto out;
  450             }
  451         }
  452 
  453         /*
  454          * Copy data into the output buffer.
  455          * Report the amount not copied.
  456          */
  457 
  458         ior->io_residual = b_to_q(data, count, &tp->t_outq);
  459 
  460         /*
  461          * Start hardware output.
  462          */
  463 
  464         tp->t_state &= ~TS_TTSTOP;
  465         tty_output(tp);
  466 
  467         if (tp->t_outq.c_cc > TTHIWAT(tp) ||
  468             (tp->t_state & TS_CARR_ON) == 0) {
  469 
  470             /*
  471              * Do not send reply until some characters have been sent.
  472              */
  473             ior->io_dev_ptr = (char *)tp;
  474             queue_delayed_reply(&tp->t_delayed_write, ior, char_write_done);
  475 
  476             rc = D_IO_QUEUED;
  477         }
  478 out:
  479         simple_unlock(&tp->t_lock);
  480         splx(s);
  481 
  482         if (!(ior->io_op & IO_INBAND))
  483             (void) vm_deallocate(device_io_map, addr, ior->io_count);
  484         return rc;
  485 }
  486 
  487 /*
  488  * Retry wait for output queue emptied, for write.
  489  * No locks may be held.
  490  * May run on any CPU.
  491  */
  492 boolean_t char_write_done(
  493         register io_req_t       ior)
  494 {
  495         register struct tty *tp = (struct tty *)ior->io_dev_ptr;
  496         register spl_t s = spltty();
  497 
  498         simple_lock(&tp->t_lock);
  499         if (tp->t_outq.c_cc > TTHIWAT(tp) ||
  500             (tp->t_state & TS_CARR_ON) == 0) {
  501 
  502             queue_delayed_reply(&tp->t_delayed_write, ior, char_write_done);
  503             simple_unlock(&tp->t_lock);
  504             splx(s);
  505             return FALSE;
  506         }
  507         simple_unlock(&tp->t_lock);
  508         splx(s);
  509 
  510         if (IP_VALID(ior->io_reply_port)) {
  511             (void) ds_device_write_reply(ior->io_reply_port,
  512                                 ior->io_reply_port_type,
  513                                 ior->io_error,
  514                                 (int)(ior->io_count - ior->io_residual));
  515         }
  516         device_deallocate(ior->io_device);
  517         return TRUE;
  518 }
  519 
  520 boolean_t tty_close_write_reply(
  521         register io_req_t       ior)
  522 {
  523         ior->io_residual = ior->io_count;
  524         ior->io_error = D_DEVICE_DOWN;
  525         (void) ds_write_done(ior);
  526         return TRUE;
  527 }
  528 
  529 /*
  530  * Read from TTY.
  531  * No locks may be held.
  532  * May run on any CPU - does not talk to device driver.
  533  */
  534 io_return_t char_read(
  535         register struct tty *tp,
  536         register io_req_t ior)
  537 {
  538         spl_t           s;
  539         kern_return_t   rc;
  540 
  541         /*
  542          * Allocate memory for read buffer.
  543          */
  544         rc = device_read_alloc(ior, (vm_size_t)ior->io_count);
  545         if (rc != KERN_SUCCESS)
  546             return rc;
  547 
  548         s = spltty();
  549         simple_lock(&tp->t_lock);
  550         if ((tp->t_state & TS_CARR_ON) == 0) {
  551 
  552             if ((tp->t_state & TS_ONDELAY) == 0) {
  553                 /*
  554                  * No delayed writes - tell caller that device is down
  555                  */
  556                 rc = D_IO_ERROR;
  557                 goto out;
  558             }
  559 
  560             if (ior->io_mode & D_NOWAIT) {
  561                 rc = D_WOULD_BLOCK;
  562                 goto out;
  563             }
  564 
  565         }
  566 
  567         if (tp->t_inq.c_cc <= 0 ||
  568             (tp->t_state & TS_CARR_ON) == 0) {
  569 
  570             ior->io_dev_ptr = (char *)tp;
  571             queue_delayed_reply(&tp->t_delayed_read, ior, char_read_done);
  572             rc = D_IO_QUEUED;
  573             goto out;
  574         }
  575         
  576         ior->io_residual = ior->io_count - q_to_b(&tp->t_inq,
  577                                                   ior->io_data,
  578                                                   (int)ior->io_count);
  579 out:
  580         simple_unlock(&tp->t_lock);
  581         splx(s);
  582         return rc;
  583 }
  584 
  585 /*
  586  * Retry wait for characters, for read.
  587  * No locks may be held.
  588  * May run on any CPU - does not talk to device driver.
  589  */
  590 boolean_t char_read_done(
  591         register io_req_t       ior)
  592 {
  593         register struct tty *tp = (struct tty *)ior->io_dev_ptr;
  594         register spl_t s = spltty();
  595 
  596         simple_lock(&tp->t_lock);
  597 
  598         if (tp->t_inq.c_cc <= 0 ||
  599             (tp->t_state & TS_CARR_ON) == 0) {
  600 
  601             queue_delayed_reply(&tp->t_delayed_read, ior, char_read_done);
  602             simple_unlock(&tp->t_lock);
  603             splx(s);
  604             return FALSE;
  605         }
  606 
  607         ior->io_residual = ior->io_count - q_to_b(&tp->t_inq,
  608                                                   ior->io_data,
  609                                                   (int)ior->io_count);
  610         simple_unlock(&tp->t_lock);
  611         splx(s);
  612 
  613         (void) ds_read_done(ior);
  614         return TRUE;
  615 }
  616 
  617 boolean_t tty_close_read_reply(
  618         register io_req_t       ior)
  619 {
  620         ior->io_residual = ior->io_count;
  621         ior->io_error = D_DEVICE_DOWN;
  622         (void) ds_read_done(ior);
  623         return TRUE;
  624 }
  625 
  626 /*
  627  * Close the tty.
  628  * Tty must be locked (at spltty).
  629  * Iff modem control should run on master.
  630  */
  631 void ttyclose(
  632         register struct tty *tp)
  633 {
  634         register io_req_t       ior;
  635 
  636         /*
  637          * Flush the read and write queues.  Signal
  638          * the open queue so that those waiting for open
  639          * to complete will see that the tty is closed.
  640          */
  641         while ((ior = (io_req_t)dequeue_head(&tp->t_delayed_read)) != 0) {
  642             ior->io_done = tty_close_read_reply;
  643             iodone(ior);
  644         }
  645         while ((ior = (io_req_t)dequeue_head(&tp->t_delayed_write)) != 0) {
  646             ior->io_done = tty_close_write_reply;
  647             iodone(ior);
  648         }
  649         while ((ior = (io_req_t)dequeue_head(&tp->t_delayed_open)) != 0) {
  650             ior->io_done = tty_close_open_reply;
  651             iodone(ior);
  652         }
  653 
  654         /* Close down modem */
  655         if (tp->t_mctl) {
  656                 (*tp->t_mctl)(tp, TM_BRK|TM_RTS, DMBIC);
  657                 if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN)==0)
  658                         (*tp->t_mctl)(tp, TM_HUP, DMSET);
  659         }
  660 
  661         /* only save buffering bit, and carrier */
  662         tp->t_state = tp->t_state & (TS_MIN|TS_CARR_ON);
  663 }
  664 
  665 /*
  666  * Port-death routine to clean up reply messages.
  667  */
  668 boolean_t
  669 tty_queue_clean(
  670         queue_t         q,
  671         ipc_port_t      port,
  672         boolean_t       (*routine)(io_req_t) )
  673 {
  674         register io_req_t       ior;
  675 
  676         ior = (io_req_t)queue_first(q);
  677         while (!queue_end(q, (queue_entry_t)ior)) {
  678             if (ior->io_reply_port == port) {
  679                 remqueue(q, (queue_entry_t)ior);
  680                 ior->io_done = routine;
  681                 iodone(ior);
  682                 return TRUE;
  683             }
  684             ior = ior->io_next;
  685         }
  686         return FALSE;
  687 }
  688 
  689 /*
  690  * Handle port-death (dead reply port) for tty.
  691  * No locks may be held.
  692  * May run on any CPU.
  693  */
  694 boolean_t
  695 tty_portdeath(
  696         struct tty *    tp,
  697         ipc_port_t      port)
  698 {
  699         register spl_t  spl = spltty();
  700         register boolean_t      result;
  701 
  702         simple_lock(&tp->t_lock);
  703 
  704         /*
  705          * The queues may never have been initialized
  706          */
  707         if (tp->t_delayed_read.next == 0) {
  708             result = FALSE;
  709         }
  710         else {
  711             result =
  712                 tty_queue_clean(&tp->t_delayed_read,  port,
  713                                 tty_close_read_reply)
  714              || tty_queue_clean(&tp->t_delayed_write, port,
  715                                 tty_close_write_reply)
  716              || tty_queue_clean(&tp->t_delayed_open,  port,
  717                                 tty_close_open_reply);
  718         }
  719         simple_unlock(&tp->t_lock);
  720         splx(spl);
  721 
  722         return result;
  723 }
  724 
  725 /*
  726  * Get TTY status.
  727  * No locks may be held.
  728  * May run on any CPU.
  729  */
  730 io_return_t tty_get_status(
  731         register struct tty *tp,
  732         dev_flavor_t    flavor,
  733         int *           data,           /* pointer to OUT array */
  734         natural_t       *count)         /* out */
  735 {
  736         spl_t           s;
  737 
  738         switch (flavor) {
  739             case TTY_STATUS:
  740             {
  741                 register struct tty_status *tsp =
  742                         (struct tty_status *) data;
  743 
  744                 if (*count < TTY_STATUS_COUNT)
  745                     return D_INVALID_OPERATION;
  746                 
  747                 s = spltty();
  748                 simple_lock(&tp->t_lock);
  749 
  750                 tsp->tt_ispeed = tp->t_ispeed;
  751                 tsp->tt_ospeed = tp->t_ospeed;
  752                 tsp->tt_breakc = tp->t_breakc;
  753                 tsp->tt_flags  = tp->t_flags;
  754                 if (tp->t_state & TS_HUPCLS)
  755                     tsp->tt_flags |= TF_HUPCLS;
  756 
  757                 simple_unlock(&tp->t_lock);
  758                 splx(s);
  759 
  760                 *count = TTY_STATUS_COUNT;
  761                 break;
  762 
  763             }
  764             default:
  765                 return D_INVALID_OPERATION;
  766         }
  767         return D_SUCCESS;
  768 }
  769 
  770 /*
  771  * Set TTY status.
  772  * No locks may be held.
  773  * Calls device start or stop routines; must already be on master if
  774  * device needs to run on master.
  775  */
  776 io_return_t tty_set_status(
  777         register struct tty *tp,
  778         dev_flavor_t    flavor,
  779         int *           data,
  780         natural_t       count)
  781 {
  782         int     s;
  783 
  784         switch (flavor) {
  785             case TTY_FLUSH:
  786             {
  787                 register int    flags;
  788                 if (count < TTY_FLUSH_COUNT)
  789                     return D_INVALID_OPERATION;
  790 
  791                 flags = *data;
  792                 if (flags == 0)
  793                     flags = D_READ | D_WRITE;
  794 
  795                 s = spltty();
  796                 simple_lock(&tp->t_lock);
  797                 tty_flush(tp, flags);
  798                 simple_unlock(&tp->t_lock);
  799                 splx(s);
  800 
  801                 break;
  802             }
  803             case TTY_STOP:
  804                 /* stop output */
  805                 s = spltty();
  806                 simple_lock(&tp->t_lock);
  807                 if ((tp->t_state & TS_TTSTOP) == 0) {
  808                     tp->t_state |= TS_TTSTOP;
  809                     (*tp->t_stop)(tp, 0);
  810                 }
  811                 simple_unlock(&tp->t_lock);
  812                 splx(s);
  813                 break;
  814 
  815             case TTY_START:
  816                 /* start output */
  817                 s = spltty();
  818                 simple_lock(&tp->t_lock);
  819                 if (tp->t_state & TS_TTSTOP) {
  820                     tp->t_state &= ~TS_TTSTOP;
  821                     tty_output(tp);
  822                 }
  823                 simple_unlock(&tp->t_lock);
  824                 splx(s);
  825                 break;
  826 
  827             case TTY_STATUS:
  828                 /* set special characters and speed */
  829             {
  830                 register struct tty_status *tsp;
  831 
  832                 if (count < TTY_STATUS_COUNT)
  833                     return D_INVALID_OPERATION;
  834 
  835                 tsp = (struct tty_status *)data;
  836 
  837                 if (tsp->tt_ispeed < 0 ||
  838                     tsp->tt_ispeed >= NSPEEDS ||
  839                     tsp->tt_ospeed < 0 ||
  840                     tsp->tt_ospeed >= NSPEEDS)
  841                 {
  842                     return D_INVALID_OPERATION;
  843                 }
  844 
  845                 s = spltty();
  846                 simple_lock(&tp->t_lock);
  847 
  848                 tp->t_ispeed = tsp->tt_ispeed;
  849                 tp->t_ospeed = tsp->tt_ospeed;
  850                 tp->t_breakc = tsp->tt_breakc;
  851                 tp->t_flags  = tsp->tt_flags & ~TF_HUPCLS;
  852                 if (tsp->tt_flags & TF_HUPCLS)
  853                     tp->t_state |= TS_HUPCLS;
  854 
  855                 simple_unlock(&tp->t_lock);
  856                 splx(s);
  857                 break;
  858             }
  859             default:
  860                 return D_INVALID_OPERATION;
  861         }
  862         return D_SUCCESS;
  863 }
  864 
  865 
  866 /*
  867  * [internal]
  868  * Queue IOR on reply queue, to wait for TTY operation.
  869  * TTY must be locked (at spltty).
  870  */
  871 void queue_delayed_reply(
  872         queue_t         qh,
  873         io_req_t        ior,
  874         boolean_t       (*io_done)(io_req_t) )
  875 {
  876         ior->io_done = io_done;
  877         enqueue_tail(qh, (queue_entry_t)ior);
  878 }
  879 
  880 /*
  881  * Retry delayed IO operations for TTY.
  882  * TTY containing queue must be locked (at spltty).
  883  */
  884 void tty_queue_completion(
  885         register queue_t        qh)
  886 {
  887         register io_req_t       ior;
  888 
  889         while ((ior = (io_req_t)dequeue_head(qh)) != 0) {
  890             iodone(ior);
  891         }
  892 }
  893 
  894 /*
  895  * Set the default special characters.
  896  * Since this routine is called whenever a tty has never been opened,
  897  * we can initialize the queues here.
  898  */
  899 void ttychars(
  900         register struct tty *tp)
  901 {
  902         if ((tp->t_flags & TS_INIT) == 0) {
  903             /*
  904              * Initialize queues
  905              */
  906             queue_init(&tp->t_delayed_open);
  907             queue_init(&tp->t_delayed_read);
  908             queue_init(&tp->t_delayed_write);
  909 
  910             /*
  911              * Initialize character buffers
  912              */
  913             cb_alloc(&tp->t_inq,  tty_inq_size);
  914 
  915             /* if we might do modem flow control */
  916             if (tp->t_mctl && tp->t_inq.c_hog > 30)
  917                 tp->t_inq.c_hog -= 30;
  918 
  919             cb_alloc(&tp->t_outq, tty_outq_size);
  920 
  921             /*
  922              * Mark initialized
  923              */
  924             tp->t_state |= TS_INIT;
  925         }
  926 
  927         tp->t_breakc = 0;
  928 }
  929 
  930 /*
  931  * Flush all TTY queues.
  932  * Called at spltty, tty already locked.
  933  * Calls device STOP routine; must already be on master if
  934  * device needs to run on master.
  935  */
  936 void tty_flush(
  937         register struct tty *tp,
  938         int     rw)
  939 {
  940         if (rw & D_READ) {
  941             cb_clear(&tp->t_inq);
  942             tty_queue_completion(&tp->t_delayed_read);
  943         }
  944         if (rw & D_WRITE) {
  945             tp->t_state &= ~TS_TTSTOP;
  946             (*tp->t_stop)(tp, rw);
  947             cb_clear(&tp->t_outq);
  948             tty_queue_completion(&tp->t_delayed_write);
  949         }
  950 }
  951                 
  952 /*
  953  * Restart character output after a delay timeout.
  954  * Calls device start routine - must be on master CPU.
  955  *
  956  *      Timeout routines are called only on master CPU.
  957  *      What if device runs on a different CPU?
  958  */
  959 void ttrstrt(
  960         register struct tty *tp)
  961 {
  962         register spl_t  s;
  963 
  964         s = spltty();
  965         simple_lock(&tp->t_lock);
  966 
  967         tp->t_state &= ~TS_TIMEOUT;
  968         if ((tp->t_state & (TS_TTSTOP | TS_BUSY)) == 0) {
  969             /*
  970              * Not busy - start output.
  971              */
  972             (*tp->t_start)(tp);
  973 
  974             /*
  975              * If output buffer has been drained,
  976              * wake up writers.
  977              */
  978             if (tp->t_outq.c_cc <= TTLOWAT(tp))
  979                 tty_queue_completion(&tp->t_delayed_write);
  980         }
  981 
  982         simple_unlock(&tp->t_lock);
  983         splx(s);
  984 }
  985 
  986 /*
  987  * Start character output, if the device is not busy or
  988  * stopped or waiting for a timeout.
  989  *
  990  * Called at spltty, tty already locked.
  991  * Must be on master CPU if device runs on master.
  992  */
  993 void tty_output(
  994         register struct tty *tp)
  995 {
  996         if ((tp->t_state & (TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) == 0) {
  997             /*
  998              * Not busy.  Start output.
  999              */
 1000             (*tp->t_start)(tp);
 1001 
 1002             /*
 1003              * Wake up those waiting for write completion.
 1004              */
 1005             if (tp->t_outq.c_cc <= TTLOWAT(tp))
 1006                 tty_queue_completion(&tp->t_delayed_write);
 1007         }
 1008 }
 1009 
 1010 /*
 1011  * Send any buffered recvd chars up to user
 1012  */
 1013 void ttypush(
 1014         register struct tty     *tp)
 1015 {
 1016         spl_t   s = spltty();
 1017         register int    state;
 1018 
 1019         simple_lock(&tp->t_lock);
 1020 
 1021         /*
 1022           The pdma timeout has gone off. 
 1023           If no character has been received since the timeout
 1024           was set, push any pending characters up.
 1025           If any characters were received in the last interval
 1026           then just reset the timeout and the character received bit.
 1027           */
 1028 
 1029         state = tp->t_state;
 1030 
 1031         if (state & TS_MIN_TO)
 1032           {
 1033             if (state & TS_MIN_TO_RCV)
 1034               { /* a character was received */
 1035                 tp->t_state = state & ~TS_MIN_TO_RCV;
 1036                 timeout(ttypush,tp,pdma_timeouts[tp->t_ispeed]);
 1037               }
 1038             else
 1039               {
 1040                 tp->t_state = state & ~TS_MIN_TO;
 1041                 if (tp->t_inq.c_cc) /* pending characters */
 1042                   tty_queue_completion(&tp->t_delayed_read);
 1043               }
 1044           }
 1045         else
 1046           {
 1047             tp->t_state = state & ~TS_MIN_TO_RCV;/* sanity */
 1048           }
 1049 
 1050         simple_unlock(&tp->t_lock);
 1051         splx(s);
 1052 }
 1053 
 1054 /*
 1055  * Put input character on input queue.
 1056  *
 1057  * Called at spltty, tty already locked.
 1058  */
 1059 void ttyinput(
 1060         unsigned int    c,
 1061         struct tty      *tp)
 1062 {
 1063   if (tp->t_inq.c_cc >= tp->t_inq.c_hog) {
 1064     /*
 1065      * Do not want to overflow input queue
 1066      */
 1067     if (tp->t_mctl) {
 1068         (*tp->t_mctl)(tp, TM_RTS, DMBIC);
 1069         tp->t_state |= TS_RTS_DOWN;
 1070     }
 1071     tty_queue_completion(&tp->t_delayed_read);
 1072     return;
 1073 
 1074   } else if (tp->t_state & TS_RTS_DOWN) {
 1075     (*tp->t_mctl)(tp, TM_RTS, DMBIS);
 1076     tp->t_state &= ~TS_RTS_DOWN;
 1077   }
 1078 
 1079   c &= 0xff;
 1080 
 1081   (void) putc(c, &tp->t_inq);
 1082   if ((tp->t_state & TS_MIN) == 0 ||
 1083         tp->t_inq.c_cc > pdma_water_mark[tp->t_ispeed])
 1084      {
 1085           /*
 1086            * No input buffering, or input minimum exceeded.
 1087            * Grab a request from input queue and queue it
 1088            * to io_done thread.
 1089            */
 1090           if (tp->t_state & TS_MIN_TO) {
 1091             tp->t_state &= ~(TS_MIN_TO|TS_MIN_TO_RCV);
 1092             untimeout(ttypush, tp);
 1093           }
 1094           tty_queue_completion(&tp->t_delayed_read);
 1095       }
 1096       else {
 1097         /*
 1098          * Not enough characters. 
 1099          * If no timeout is set, initiate the timeout 
 1100          * Otherwise set the character received during timeout interval
 1101          * flag.
 1102          * One alternative approach would be just to reset the timeout
 1103          * into the future, but this involves making a timeout/untimeout
 1104          * call on every character.
 1105          */
 1106         register int ptime = pdma_timeouts[tp->t_ispeed];
 1107         if (ptime > 0)
 1108           {
 1109             if ((tp->t_state & TS_MIN_TO) == 0)
 1110               {
 1111                 tp->t_state |= TS_MIN_TO;
 1112                 timeout(ttypush, tp, ptime);
 1113               }
 1114             else
 1115               {
 1116                 tp->t_state |= TS_MIN_TO_RCV;
 1117               }
 1118           }
 1119       }
 1120 }
 1121 
 1122 /*
 1123  * Put many characters on input queue.
 1124  *
 1125  * Called at spltty, tty already locked.
 1126  */
 1127 void ttyinput_many(
 1128         struct tty      *tp,
 1129         unsigned char   *chars,
 1130         int             count)
 1131 {
 1132         /*
 1133          * Do not want to overflow input queue 
 1134          */
 1135         if (tp->t_inq.c_cc < tp->t_inq.c_hog)
 1136                 count -= b_to_q( chars, count, &tp->t_inq);
 1137 
 1138         tty_queue_completion(&tp->t_delayed_read);
 1139 }
 1140 
 1141 
 1142 /*
 1143  * Handle modem control transition on a tty.
 1144  * Flag indicates new state of carrier.
 1145  * Returns FALSE if the line should be turned off.
 1146  *
 1147  * Called at spltty, tty already locked.
 1148  */
 1149 boolean_t ttymodem(
 1150         struct tty *    tp,
 1151         boolean_t       carrier_up)
 1152 {
 1153         if ((tp->t_state&TS_WOPEN) == 0 && (tp->t_flags & MDMBUF)) {
 1154             /*
 1155              * Flow control by carrier.  Carrier down stops
 1156              * output; carrier up restarts output.
 1157              */
 1158             if (carrier_up) {
 1159                 tp->t_state &= ~TS_TTSTOP;
 1160                 tty_output(tp);
 1161             }
 1162             else if ((tp->t_state&TS_TTSTOP) == 0) {
 1163                 tp->t_state |= TS_TTSTOP;
 1164                 (*tp->t_stop)(tp, 0);
 1165             }
 1166         }
 1167         else if (carrier_up) {
 1168             /*
 1169              * Carrier now on.
 1170              */
 1171             tp->t_state |= TS_CARR_ON;
 1172             tt_open_wakeup(tp);
 1173         }
 1174         else {
 1175             /*
 1176              * Lost carrier.
 1177              */
 1178             tp->t_state &= ~TS_CARR_ON;
 1179             if (tp->t_state & TS_ISOPEN &&
 1180                 (tp->t_flags & NOHANG) == 0)
 1181             {
 1182                 /*
 1183                  * Hang up TTY if carrier drops.
 1184                  * Need to alert users, somehow...
 1185                  */
 1186                 tty_flush(tp, D_READ|D_WRITE);
 1187                 return FALSE;
 1188             }
 1189         }
 1190         return TRUE;
 1191 }
 1192 
 1193 /*
 1194  * Similarly, handle transitions on the ClearToSend
 1195  * signal.  Nowadays, it is used by many modems as
 1196  * a flow-control device: they turn it down to stop
 1197  * us from sending more chars.  We do the same with
 1198  * the RequestToSend signal. [Yes, that is exactly
 1199  * why those signals are defined in the standard.]
 1200  *
 1201  * Tty must be locked and on master.
 1202  */
 1203 void tty_cts(
 1204         struct tty *    tp,
 1205         boolean_t       cts_up)
 1206 {
 1207         if (tp->t_state & TS_ISOPEN){
 1208                 if (cts_up) {
 1209                         tp->t_state &= ~(TS_TTSTOP|TS_BUSY);
 1210                         tty_output(tp);
 1211                 } else {
 1212                         tp->t_state |= (TS_TTSTOP|TS_BUSY);
 1213                         (*tp->t_stop)(tp, D_WRITE);
 1214                 }
 1215         }
 1216 }

Cache object: 46f0790527e2117047d1bdc3a14c35c8


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