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

Cache object: 2349482ee7a823f1a1193fcca067bd86


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