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/cirbuf.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 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:        cirbuf.c,v $
   29  * Revision 2.11  93/11/17  16:30:00  dbg
   30  *      Added import of kern/memory.h for bcopy.
   31  *      [93/10/27            dbg]
   32  * 
   33  * Revision 2.10  93/05/17  10:31:09  rvb
   34  *      Fixed nasty bug in getc(): it was returning -1 when
   35  *      the character was 0xff. This makes SLIP work on DS boxes.
   36  *      [93/05/13  20:28:59  af]
   37  * 
   38  * Revision 2.9  93/01/14  17:26:33  danner
   39  *      Added function prototypes.  Added cb_clear.
   40  *      [92/11/17            dbg]
   41  * 
   42  * Revision 2.8  92/08/03  17:32:56  jfriedl
   43  *      removed silly prototypes
   44  *      [92/08/02            jfriedl]
   45  * 
   46  * Revision 2.7  92/05/21  17:08:44  jfriedl
   47  *      tried prototypes.
   48  *      [92/05/20            jfriedl]
   49  * 
   50  * Revision 2.6  92/05/05  10:46:15  danner
   51  *      Initialize c_hog.
   52  *      [92/05/04            af]
   53  * 
   54  * Revision 2.5  91/07/31  17:32:09  dbg
   55  *      Put CB_CHECK under debugging switch.
   56  *      [91/07/30  16:45:34  dbg]
   57  * 
   58  * Revision 2.4  91/05/14  15:39:25  mrt
   59  *      Correcting copyright
   60  * 
   61  * Revision 2.3  91/02/05  17:08:01  mrt
   62  *      Changed to new Mach copyright
   63  *      [91/01/31  17:26:33  mrt]
   64  * 
   65  * Revision 2.2  90/08/27  21:54:30  dbg
   66  *      q_to_b was always emptying the circular buffer; fix it.
   67  *      [90/08/06            dbg]
   68  *      Created.
   69  *      [90/07/09            dbg]
   70  * 
   71  */
   72 /*
   73  *      Author: David B. Golub, Carnegie Mellon University
   74  *      Date:   7/90
   75  *
   76  *      Circular buffers for TTY
   77  */
   78 
   79 #include <device/cirbuf.h>
   80 #include <kern/kalloc.h>
   81 #include <kern/memory.h>
   82 
   83 
   84 
   85 /* read at c_cf, write at c_cl */
   86 /* if c_cf == c_cl, buffer is empty */
   87 /* if c_cl == c_cf - 1, buffer is full */
   88 
   89 #if     DEBUG
   90 int cb_check_enable = 0;
   91 #define CB_CHECK(cb) if (cb_check_enable) cb_check(cb)
   92 
   93 void
   94 cb_check(register struct cirbuf *cb)
   95 {
   96         if (!(cb->c_cf >= cb->c_start && cb->c_cf < cb->c_end))
   97             panic("cf %x out of range [%x..%x)",
   98                 cb->c_cf, cb->c_start, cb->c_end);
   99         if (!(cb->c_cl >= cb->c_start && cb->c_cl < cb->c_end))
  100             panic("cl %x out of range [%x..%x)",
  101                 cb->c_cl, cb->c_start, cb->c_end);
  102         if (cb->c_cf <= cb->c_cl) {
  103             if (!(cb->c_cc == cb->c_cl - cb->c_cf))
  104                 panic("cc %x should be %x",
  105                         cb->c_cc,
  106                         cb->c_cl - cb->c_cf);
  107         }
  108         else {
  109             if (!(cb->c_cc == cb->c_end - cb->c_cf
  110                             + cb->c_cl - cb->c_start))
  111                 panic("cc %x should be %x",
  112                         cb->c_cc,
  113                         cb->c_end - cb->c_cf +
  114                         cb->c_cl - cb->c_start);
  115         }
  116 }
  117 #else   /* DEBUG */
  118 #define CB_CHECK(cb)
  119 #endif  /* DEBUG */
  120 
  121 /*
  122  * Put one character in circular buffer.
  123  */
  124 int putc(
  125         int     c,
  126         register struct cirbuf *cb)
  127 {
  128         register char *ow, *nw;
  129 
  130         ow = cb->c_cl;
  131         nw = ow+1;
  132         if (nw == cb->c_end)
  133             nw = cb->c_start;
  134         if (nw == cb->c_cf)
  135             return 1;           /* not entered */
  136         *ow = c;
  137         cb->c_cl = nw;
  138 
  139         cb->c_cc++;
  140 
  141         CB_CHECK(cb);
  142 
  143         return 0;
  144 }
  145 
  146 /*
  147  * Get one character from circular buffer.
  148  */
  149 int getc(register struct cirbuf *cb)
  150 {
  151         register unsigned char *nr;
  152         register int    c;
  153 
  154         nr = (unsigned char *)cb->c_cf;
  155         if (nr == (unsigned char *)cb->c_cl) {
  156             CB_CHECK(cb);
  157             return -1;          /* empty */
  158         }
  159         c = *nr;
  160         nr++;
  161         if (nr == (unsigned char *)cb->c_end)
  162             nr = (unsigned char *)cb->c_start;
  163         cb->c_cf = (char *)nr;
  164 
  165         cb->c_cc--;
  166 
  167         CB_CHECK(cb);
  168 
  169         return c;
  170 }
  171 
  172 /*
  173  * Get lots of characters.
  174  * Return number moved.
  175  */
  176 int
  177 q_to_b( register struct cirbuf *cb,
  178         register char   *cp,
  179         register int    count)
  180 {
  181         char *          ocp = cp;
  182         register int    i;
  183 
  184         while (count != 0) {
  185             if (cb->c_cl == cb->c_cf)
  186                 break;          /* empty */
  187             if (cb->c_cl < cb->c_cf)
  188                 i = cb->c_end - cb->c_cf;
  189             else
  190                 i = cb->c_cl - cb->c_cf;
  191             if (i > count)
  192                 i = count;
  193             bcopy(cb->c_cf, cp, i);
  194             cp += i;
  195             count -= i;
  196             cb->c_cf += i;
  197             cb->c_cc -= i;
  198             if (cb->c_cf == cb->c_end)
  199                 cb->c_cf = cb->c_start;
  200 
  201             CB_CHECK(cb);
  202         }
  203         CB_CHECK(cb);
  204 
  205         return cp - ocp;
  206 }
  207 
  208 /*
  209  * Add character array to buffer and return number of characters
  210  * NOT entered.
  211  */
  212 int
  213 b_to_q( register char * cp,
  214         int     count,
  215         register struct cirbuf *cb)
  216 {
  217         register int    i;
  218         register char   *lim;
  219 
  220         while (count != 0) {
  221             lim = cb->c_cf - 1;
  222             if (lim < cb->c_start)
  223                 lim = cb->c_end - 1;
  224 
  225             if (cb->c_cl == lim)
  226                 break;
  227             if (cb->c_cl < lim)
  228                 i = lim - cb->c_cl;
  229             else
  230                 i = cb->c_end - cb->c_cl;
  231 
  232             if (i > count)
  233                 i = count;
  234             bcopy(cp, cb->c_cl, i);
  235             cp += i;
  236             count -= i;
  237             cb->c_cc += i;
  238             cb->c_cl += i;
  239             if (cb->c_cl == cb->c_end)
  240                 cb->c_cl = cb->c_start;
  241 
  242             CB_CHECK(cb);
  243         }
  244         CB_CHECK(cb);
  245         return count;
  246 }
  247 
  248 /*
  249  * Return number of contiguous characters up to a character
  250  * that matches the mask.
  251  */
  252 int
  253 ndqb(   register struct cirbuf *cb,
  254         register int    mask)
  255 {
  256         register char *cp, *lim;
  257 
  258         if (cb->c_cl < cb->c_cf)
  259             lim = cb->c_end;
  260         else
  261             lim = cb->c_cl;
  262         if (mask == 0)
  263             return (lim - cb->c_cf);
  264         cp = cb->c_cf;
  265         while (cp < lim) {
  266             if (*cp & mask)
  267                 break;
  268             cp++;
  269         }
  270         return (cp - cb->c_cf);
  271 }
  272 
  273 /*
  274  * Flush characters from circular buffer.
  275  */
  276 void
  277 ndflush(register struct cirbuf *cb,
  278         register int    count)
  279 {
  280         register int    i;
  281 
  282         while (count != 0) {
  283             if (cb->c_cl == cb->c_cf)
  284                 break;          /* empty */
  285             if (cb->c_cl < cb->c_cf)
  286                 i = cb->c_end - cb->c_cf;
  287             else
  288                 i = cb->c_cl - cb->c_cf;
  289             if (i > count)
  290                 i = count;
  291             count -= i;
  292             cb->c_cf += i;
  293             cb->c_cc -= i;
  294             if (cb->c_cf == cb->c_end)
  295                 cb->c_cf = cb->c_start;
  296             CB_CHECK(cb);
  297         }
  298 
  299         CB_CHECK(cb);
  300 }
  301 
  302 /*
  303  * Empty a circular buffer.
  304  */
  305 void cb_clear(struct cirbuf *cb)
  306 {
  307         cb->c_cf = cb->c_start;
  308         cb->c_cl = cb->c_start;
  309         cb->c_cc = 0;
  310 }
  311 
  312 /*
  313  * Allocate character space for a circular buffer.
  314  */
  315 void
  316 cb_alloc(
  317         register struct cirbuf *cb,
  318         int             buf_size)
  319 {
  320         register char *buf;
  321 
  322         buf = (char *)kalloc(buf_size);
  323 
  324         cb->c_start = buf;
  325         cb->c_end = buf + buf_size;
  326         cb->c_cf = buf;
  327         cb->c_cl = buf;
  328         cb->c_cc = 0;
  329         cb->c_hog = buf_size - 1;
  330 
  331         CB_CHECK(cb);
  332 }
  333 
  334 /*
  335  * Free character space for a circular buffer.
  336  */
  337 void
  338 cb_free(register struct cirbuf *cb)
  339 {
  340         int             size;
  341 
  342         size = cb->c_end - cb->c_start;
  343         kfree((vm_offset_t)cb->c_start, size);
  344 }
  345 

Cache object: d1654caddcf2c5470438cb589eac7a13


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