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

Cache object: a6d2cf3a5692b25fbab61f3c6790c87b


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