summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/conf/files2
-rw-r--r--sys/kern/tty_subr.c699
2 files changed, 1 insertions, 700 deletions
diff --git a/sys/conf/files b/sys/conf/files
index f3bf976..9ede3b8 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1608,6 +1608,7 @@ kern/subr_acl_posix1e.c standard
kern/subr_autoconf.c standard
kern/subr_blist.c standard
kern/subr_bus.c standard
+kern/subr_clist.c standard
kern/subr_clock.c standard
kern/subr_devstat.c standard
kern/subr_disk.c standard
@@ -1655,7 +1656,6 @@ kern/tty_conf.c standard
kern/tty_cons.c standard
kern/tty_pts.c optional pty
kern/tty_pty.c optional pty
-kern/tty_subr.c standard
kern/tty_tty.c standard
kern/uipc_accf.c optional inet
kern/uipc_cow.c optional zero_copy_sockets
diff --git a/sys/kern/tty_subr.c b/sys/kern/tty_subr.c
deleted file mode 100644
index 57225db..0000000
--- a/sys/kern/tty_subr.c
+++ /dev/null
@@ -1,699 +0,0 @@
-/*-
- * Copyright (c) 1994, David Greenman
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice unmodified, this list of conditions, and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * clist support routines
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/tty.h>
-#include <sys/clist.h>
-
-static void clist_init(void *);
-SYSINIT(clist, SI_SUB_CLIST, SI_ORDER_FIRST, clist_init, NULL);
-
-static MALLOC_DEFINE(M_CLIST, "clist", "clist queue blocks");
-
-static struct cblock *cfreelist = 0;
-int cfreecount = 0;
-static int cslushcount;
-static int ctotcount;
-
-#ifndef INITIAL_CBLOCKS
-#define INITIAL_CBLOCKS 50
-#endif
-
-static struct cblock *cblock_alloc(void);
-static void cblock_alloc_cblocks(int number);
-static void cblock_free(struct cblock *cblockp);
-static void cblock_free_cblocks(int number);
-
-#include "opt_ddb.h"
-#ifdef DDB
-#include <ddb/ddb.h>
-
-DB_SHOW_COMMAND(cbstat, cbstat)
-{
- int cbsize = CBSIZE;
-
- printf(
- "tot = %d (active = %d, free = %d (reserved = %d, slush = %d))\n",
- ctotcount * cbsize, ctotcount * cbsize - cfreecount, cfreecount,
- cfreecount - cslushcount * cbsize, cslushcount * cbsize);
-}
-#endif /* DDB */
-
-/*
- * Called from init_main.c
- */
-/* ARGSUSED*/
-static void
-clist_init(dummy)
- void *dummy;
-{
- /*
- * Allocate an initial base set of cblocks as a 'slush'.
- * We allocate non-slush cblocks with each initial tty_open() and
- * deallocate them with each tty_close().
- * We should adjust the slush allocation. This can't be done in
- * the i/o routines because they are sometimes called from
- * interrupt handlers when it may be unsafe to call malloc().
- */
- cblock_alloc_cblocks(cslushcount = INITIAL_CBLOCKS);
-}
-
-/*
- * Remove a cblock from the cfreelist queue and return a pointer
- * to it.
- */
-static __inline struct cblock *
-cblock_alloc()
-{
- struct cblock *cblockp;
-
- cblockp = cfreelist;
- if (cblockp == NULL)
- panic("clist reservation botch");
- cfreelist = cblockp->c_next;
- cblockp->c_next = NULL;
- cfreecount -= CBSIZE;
- return (cblockp);
-}
-
-/*
- * Add a cblock to the cfreelist queue.
- */
-static __inline void
-cblock_free(cblockp)
- struct cblock *cblockp;
-{
- if (isset(cblockp->c_quote, CBQSIZE * NBBY - 1))
- bzero(cblockp->c_quote, sizeof cblockp->c_quote);
- cblockp->c_next = cfreelist;
- cfreelist = cblockp;
- cfreecount += CBSIZE;
-}
-
-/*
- * Allocate some cblocks for the cfreelist queue.
- */
-static void
-cblock_alloc_cblocks(number)
- int number;
-{
- int i;
- struct cblock *cbp;
-
- for (i = 0; i < number; ++i) {
- cbp = malloc(sizeof *cbp, M_CLIST, M_NOWAIT);
- if (cbp == NULL) {
- printf(
-"cblock_alloc_cblocks: M_NOWAIT malloc failed, trying M_WAITOK\n");
- cbp = malloc(sizeof *cbp, M_CLIST, M_WAITOK);
- }
- /*
- * Freed cblocks have zero quotes and garbage elsewhere.
- * Set the may-have-quote bit to force zeroing the quotes.
- */
- setbit(cbp->c_quote, CBQSIZE * NBBY - 1);
- cblock_free(cbp);
- }
- ctotcount += number;
-}
-
-/*
- * Set the cblock allocation policy for a clist.
- * Must be called in process context at spltty().
- */
-void
-clist_alloc_cblocks(clistp, ccmax, ccreserved)
- struct clist *clistp;
- int ccmax;
- int ccreserved;
-{
- int dcbr;
-
- /*
- * Allow for wasted space at the head.
- */
- if (ccmax != 0)
- ccmax += CBSIZE - 1;
- if (ccreserved != 0)
- ccreserved += CBSIZE - 1;
-
- clistp->c_cbmax = roundup(ccmax, CBSIZE) / CBSIZE;
- dcbr = roundup(ccreserved, CBSIZE) / CBSIZE - clistp->c_cbreserved;
- if (dcbr >= 0)
- cblock_alloc_cblocks(dcbr);
- else {
- if (clistp->c_cbreserved + dcbr < clistp->c_cbcount)
- dcbr = clistp->c_cbcount - clistp->c_cbreserved;
- cblock_free_cblocks(-dcbr);
- }
- clistp->c_cbreserved += dcbr;
-}
-
-/*
- * Free some cblocks from the cfreelist queue back to the
- * system malloc pool.
- */
-static void
-cblock_free_cblocks(number)
- int number;
-{
- int i;
-
- for (i = 0; i < number; ++i)
- free(cblock_alloc(), M_CLIST);
- ctotcount -= number;
-}
-
-/*
- * Free the cblocks reserved for a clist.
- * Must be called at spltty().
- */
-void
-clist_free_cblocks(clistp)
- struct clist *clistp;
-{
- if (clistp->c_cbcount != 0)
- panic("freeing active clist cblocks");
- cblock_free_cblocks(clistp->c_cbreserved);
- clistp->c_cbmax = 0;
- clistp->c_cbreserved = 0;
-}
-
-/*
- * Get a character from the head of a clist.
- */
-int
-getc(clistp)
- struct clist *clistp;
-{
- int chr = -1;
- int s;
- struct cblock *cblockp;
-
- s = spltty();
-
- /* If there are characters in the list, get one */
- if (clistp->c_cc) {
- cblockp = (struct cblock *)((intptr_t)clistp->c_cf & ~CROUND);
- chr = (u_char)*clistp->c_cf;
-
- /*
- * If this char is quoted, set the flag.
- */
- if (isset(cblockp->c_quote, clistp->c_cf - (char *)cblockp->c_info))
- chr |= TTY_QUOTE;
-
- /*
- * Advance to next character.
- */
- clistp->c_cf++;
- clistp->c_cc--;
- /*
- * If we have advanced the 'first' character pointer
- * past the end of this cblock, advance to the next one.
- * If there are no more characters, set the first and
- * last pointers to NULL. In either case, free the
- * current cblock.
- */
- if ((clistp->c_cf >= (char *)(cblockp+1)) || (clistp->c_cc == 0)) {
- if (clistp->c_cc > 0) {
- clistp->c_cf = cblockp->c_next->c_info;
- } else {
- clistp->c_cf = clistp->c_cl = NULL;
- }
- cblock_free(cblockp);
- if (--clistp->c_cbcount >= clistp->c_cbreserved)
- ++cslushcount;
- }
- }
-
- splx(s);
- return (chr);
-}
-
-/*
- * Copy 'amount' of chars, beginning at head of clist 'clistp' to
- * destination linear buffer 'dest'. Return number of characters
- * actually copied.
- */
-int
-q_to_b(clistp, dest, amount)
- struct clist *clistp;
- char *dest;
- int amount;
-{
- struct cblock *cblockp;
- struct cblock *cblockn;
- char *dest_orig = dest;
- int numc;
- int s;
-
- s = spltty();
-
- while (clistp && amount && (clistp->c_cc > 0)) {
- cblockp = (struct cblock *)((intptr_t)clistp->c_cf & ~CROUND);
- cblockn = cblockp + 1; /* pointer arithmetic! */
- numc = min(amount, (char *)cblockn - clistp->c_cf);
- numc = min(numc, clistp->c_cc);
- bcopy(clistp->c_cf, dest, numc);
- amount -= numc;
- clistp->c_cf += numc;
- clistp->c_cc -= numc;
- dest += numc;
- /*
- * If this cblock has been emptied, advance to the next
- * one. If there are no more characters, set the first
- * and last pointer to NULL. In either case, free the
- * current cblock.
- */
- if ((clistp->c_cf >= (char *)cblockn) || (clistp->c_cc == 0)) {
- if (clistp->c_cc > 0) {
- clistp->c_cf = cblockp->c_next->c_info;
- } else {
- clistp->c_cf = clistp->c_cl = NULL;
- }
- cblock_free(cblockp);
- if (--clistp->c_cbcount >= clistp->c_cbreserved)
- ++cslushcount;
- }
- }
-
- splx(s);
- return (dest - dest_orig);
-}
-
-/*
- * Flush 'amount' of chars, beginning at head of clist 'clistp'.
- */
-void
-ndflush(clistp, amount)
- struct clist *clistp;
- int amount;
-{
- struct cblock *cblockp;
- struct cblock *cblockn;
- int numc;
- int s;
-
- s = spltty();
-
- while (amount && (clistp->c_cc > 0)) {
- cblockp = (struct cblock *)((intptr_t)clistp->c_cf & ~CROUND);
- cblockn = cblockp + 1; /* pointer arithmetic! */
- numc = min(amount, (char *)cblockn - clistp->c_cf);
- numc = min(numc, clistp->c_cc);
- amount -= numc;
- clistp->c_cf += numc;
- clistp->c_cc -= numc;
- /*
- * If this cblock has been emptied, advance to the next
- * one. If there are no more characters, set the first
- * and last pointer to NULL. In either case, free the
- * current cblock.
- */
- if ((clistp->c_cf >= (char *)cblockn) || (clistp->c_cc == 0)) {
- if (clistp->c_cc > 0) {
- clistp->c_cf = cblockp->c_next->c_info;
- } else {
- clistp->c_cf = clistp->c_cl = NULL;
- }
- cblock_free(cblockp);
- if (--clistp->c_cbcount >= clistp->c_cbreserved)
- ++cslushcount;
- }
- }
-
- splx(s);
-}
-
-/*
- * Add a character to the end of a clist. Return -1 is no
- * more clists, or 0 for success.
- */
-int
-putc(chr, clistp)
- int chr;
- struct clist *clistp;
-{
- struct cblock *cblockp;
- int s;
-
- s = spltty();
-
- if (clistp->c_cl == NULL) {
- if (clistp->c_cbreserved < 1) {
- splx(s);
- printf("putc to a clist with no reserved cblocks\n");
- return (-1); /* nothing done */
- }
- cblockp = cblock_alloc();
- clistp->c_cbcount = 1;
- clistp->c_cf = clistp->c_cl = cblockp->c_info;
- clistp->c_cc = 0;
- } else {
- cblockp = (struct cblock *)((intptr_t)clistp->c_cl & ~CROUND);
- if (((intptr_t)clistp->c_cl & CROUND) == 0) {
- struct cblock *prev = (cblockp - 1);
-
- if (clistp->c_cbcount >= clistp->c_cbreserved) {
- if (clistp->c_cbcount >= clistp->c_cbmax
- || cslushcount <= 0) {
- splx(s);
- return (-1);
- }
- --cslushcount;
- }
- cblockp = cblock_alloc();
- clistp->c_cbcount++;
- prev->c_next = cblockp;
- clistp->c_cl = cblockp->c_info;
- }
- }
-
- /*
- * If this character is quoted, set the quote bit, if not, clear it.
- */
- if (chr & TTY_QUOTE) {
- setbit(cblockp->c_quote, clistp->c_cl - (char *)cblockp->c_info);
- /*
- * Use one of the spare quote bits to record that something
- * may be quoted.
- */
- setbit(cblockp->c_quote, CBQSIZE * NBBY - 1);
- } else
- clrbit(cblockp->c_quote, clistp->c_cl - (char *)cblockp->c_info);
-
- *clistp->c_cl++ = chr;
- clistp->c_cc++;
-
- splx(s);
- return (0);
-}
-
-/*
- * Copy data from linear buffer to clist chain. Return the
- * number of characters not copied.
- */
-int
-b_to_q(src, amount, clistp)
- char *src;
- int amount;
- struct clist *clistp;
-{
- struct cblock *cblockp;
- char *firstbyte, *lastbyte;
- u_char startmask, endmask;
- int startbit, endbit, num_between, numc;
- int s;
-
- /*
- * Avoid allocating an initial cblock and then not using it.
- * c_cc == 0 must imply c_cbount == 0.
- */
- if (amount <= 0)
- return (amount);
-
- s = spltty();
-
- /*
- * If there are no cblocks assigned to this clist yet,
- * then get one.
- */
- if (clistp->c_cl == NULL) {
- if (clistp->c_cbreserved < 1) {
- splx(s);
- printf("b_to_q to a clist with no reserved cblocks.\n");
- return (amount); /* nothing done */
- }
- cblockp = cblock_alloc();
- clistp->c_cbcount = 1;
- clistp->c_cf = clistp->c_cl = cblockp->c_info;
- clistp->c_cc = 0;
- } else {
- cblockp = (struct cblock *)((intptr_t)clistp->c_cl & ~CROUND);
- }
-
- while (amount) {
- /*
- * Get another cblock if needed.
- */
- if (((intptr_t)clistp->c_cl & CROUND) == 0) {
- struct cblock *prev = cblockp - 1;
-
- if (clistp->c_cbcount >= clistp->c_cbreserved) {
- if (clistp->c_cbcount >= clistp->c_cbmax
- || cslushcount <= 0) {
- splx(s);
- return (amount);
- }
- --cslushcount;
- }
- cblockp = cblock_alloc();
- clistp->c_cbcount++;
- prev->c_next = cblockp;
- clistp->c_cl = cblockp->c_info;
- }
-
- /*
- * Copy a chunk of the linear buffer up to the end
- * of this cblock.
- */
- numc = min(amount, (char *)(cblockp + 1) - clistp->c_cl);
- bcopy(src, clistp->c_cl, numc);
-
- /*
- * Clear quote bits if they aren't known to be clear.
- * The following could probably be made into a separate
- * "bitzero()" routine, but why bother?
- */
- if (isset(cblockp->c_quote, CBQSIZE * NBBY - 1)) {
- startbit = clistp->c_cl - (char *)cblockp->c_info;
- endbit = startbit + numc - 1;
-
- firstbyte = (u_char *)cblockp->c_quote + (startbit / NBBY);
- lastbyte = (u_char *)cblockp->c_quote + (endbit / NBBY);
-
- /*
- * Calculate mask of bits to preserve in first and
- * last bytes.
- */
- startmask = NBBY - (startbit % NBBY);
- startmask = 0xff >> startmask;
- endmask = (endbit % NBBY);
- endmask = 0xff << (endmask + 1);
-
- if (firstbyte != lastbyte) {
- *firstbyte &= startmask;
- *lastbyte &= endmask;
-
- num_between = lastbyte - firstbyte - 1;
- if (num_between)
- bzero(firstbyte + 1, num_between);
- } else {
- *firstbyte &= (startmask | endmask);
- }
- }
-
- /*
- * ...and update pointer for the next chunk.
- */
- src += numc;
- clistp->c_cl += numc;
- clistp->c_cc += numc;
- amount -= numc;
- /*
- * If we go through the loop again, it's always
- * for data in the next cblock, so by adding one (cblock),
- * (which makes the pointer 1 beyond the end of this
- * cblock) we prepare for the assignment of 'prev'
- * above.
- */
- cblockp += 1;
-
- }
-
- splx(s);
- return (amount);
-}
-
-/*
- * Get the next character in the clist. Store it at dst. Don't
- * advance any clist pointers, but return a pointer to the next
- * character position.
- */
-char *
-nextc(clistp, cp, dst)
- struct clist *clistp;
- char *cp;
- int *dst;
-{
- struct cblock *cblockp;
-
- ++cp;
- /*
- * See if the next character is beyond the end of
- * the clist.
- */
- if (clistp->c_cc && (cp != clistp->c_cl)) {
- /*
- * If the next character is beyond the end of this
- * cblock, advance to the next cblock.
- */
- if (((intptr_t)cp & CROUND) == 0)
- cp = ((struct cblock *)cp - 1)->c_next->c_info;
- cblockp = (struct cblock *)((intptr_t)cp & ~CROUND);
-
- /*
- * Get the character. Set the quote flag if this character
- * is quoted.
- */
- *dst = (u_char)*cp | (isset(cblockp->c_quote, cp - (char *)cblockp->c_info) ? TTY_QUOTE : 0);
-
- return (cp);
- }
-
- return (NULL);
-}
-
-/*
- * "Unput" a character from a clist.
- */
-int
-unputc(clistp)
- struct clist *clistp;
-{
- struct cblock *cblockp = 0, *cbp = 0;
- int s;
- int chr = -1;
-
-
- s = spltty();
-
- if (clistp->c_cc) {
- --clistp->c_cc;
- --clistp->c_cl;
-
- chr = (u_char)*clistp->c_cl;
-
- cblockp = (struct cblock *)((intptr_t)clistp->c_cl & ~CROUND);
-
- /*
- * Set quote flag if this character was quoted.
- */
- if (isset(cblockp->c_quote, (u_char *)clistp->c_cl - cblockp->c_info))
- chr |= TTY_QUOTE;
-
- /*
- * If all of the characters have been unput in this
- * cblock, then find the previous one and free this
- * one.
- */
- if (clistp->c_cc && (clistp->c_cl <= (char *)cblockp->c_info)) {
- cbp = (struct cblock *)((intptr_t)clistp->c_cf & ~CROUND);
-
- while (cbp->c_next != cblockp)
- cbp = cbp->c_next;
-
- /*
- * When the previous cblock is at the end, the 'last'
- * pointer always points (invalidly) one past.
- */
- clistp->c_cl = (char *)(cbp+1);
- cblock_free(cblockp);
- if (--clistp->c_cbcount >= clistp->c_cbreserved)
- ++cslushcount;
- cbp->c_next = NULL;
- }
- }
-
- /*
- * If there are no more characters on the list, then
- * free the last cblock.
- */
- if ((clistp->c_cc == 0) && clistp->c_cl) {
- cblockp = (struct cblock *)((intptr_t)clistp->c_cl & ~CROUND);
- cblock_free(cblockp);
- if (--clistp->c_cbcount >= clistp->c_cbreserved)
- ++cslushcount;
- clistp->c_cf = clistp->c_cl = NULL;
- }
-
- splx(s);
- return (chr);
-}
-
-/*
- * Move characters in source clist to destination clist,
- * preserving quote bits.
- */
-void
-catq(src_clistp, dest_clistp)
- struct clist *src_clistp, *dest_clistp;
-{
- int chr, s;
-
- s = spltty();
- /*
- * If the destination clist is empty (has no cblocks atttached),
- * and there are no possible complications with the resource counters,
- * then we simply assign the current clist to the destination.
- */
- if (!dest_clistp->c_cf
- && src_clistp->c_cbcount <= src_clistp->c_cbmax
- && src_clistp->c_cbcount <= dest_clistp->c_cbmax) {
- dest_clistp->c_cf = src_clistp->c_cf;
- dest_clistp->c_cl = src_clistp->c_cl;
- src_clistp->c_cf = src_clistp->c_cl = NULL;
-
- dest_clistp->c_cc = src_clistp->c_cc;
- src_clistp->c_cc = 0;
- dest_clistp->c_cbcount = src_clistp->c_cbcount;
- src_clistp->c_cbcount = 0;
-
- splx(s);
- return;
- }
-
- splx(s);
-
- /*
- * XXX This should probably be optimized to more than one
- * character at a time.
- */
- while ((chr = getc(src_clistp)) != -1)
- putc(chr, dest_clistp);
-}
OpenPOWER on IntegriCloud