1181905Sed/*-
2181905Sed * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org>
3181905Sed * All rights reserved.
4181905Sed *
5181905Sed * Portions of this software were developed under sponsorship from Snow
6181905Sed * B.V., the Netherlands.
7181905Sed *
8181905Sed * Redistribution and use in source and binary forms, with or without
9181905Sed * modification, are permitted provided that the following conditions
10181905Sed * are met:
11181905Sed * 1. Redistributions of source code must retain the above copyright
12181905Sed *    notice, this list of conditions and the following disclaimer.
13181905Sed * 2. Redistributions in binary form must reproduce the above copyright
14181905Sed *    notice, this list of conditions and the following disclaimer in the
15181905Sed *    documentation and/or other materials provided with the distribution.
16181905Sed *
17181905Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18181905Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19181905Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20181905Sed * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21181905Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22181905Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23181905Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24181905Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25181905Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26181905Sed * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27181905Sed * SUCH DAMAGE.
28181905Sed *
29181905Sed * $FreeBSD$
30181905Sed */
31181905Sed
32181905Sed#ifndef _SYS_TTYQUEUE_H_
33181905Sed#define	_SYS_TTYQUEUE_H_
34181905Sed
35181905Sed#ifndef _SYS_TTY_H_
36181905Sed#error "can only be included through <sys/tty.h>"
37181905Sed#endif /* !_SYS_TTY_H_ */
38181905Sed
39181905Sedstruct tty;
40181905Sedstruct ttyinq_block;
41181905Sedstruct ttyoutq_block;
42181905Sedstruct uio;
43181905Sed
44181905Sed/* Data input queue. */
45181905Sedstruct ttyinq {
46188096Sed	struct ttyinq_block	*ti_firstblock;
47188096Sed	struct ttyinq_block	*ti_startblock;
48188096Sed	struct ttyinq_block	*ti_reprintblock;
49188096Sed	struct ttyinq_block	*ti_lastblock;
50188096Sed	unsigned int		ti_begin;
51188096Sed	unsigned int		ti_linestart;
52188096Sed	unsigned int		ti_reprint;
53188096Sed	unsigned int		ti_end;
54188096Sed	unsigned int		ti_nblocks;
55188096Sed	unsigned int		ti_quota;
56181905Sed};
57181905Sed#define TTYINQ_DATASIZE 128
58181905Sed
59181905Sed/* Data output queue. */
60181905Sedstruct ttyoutq {
61188096Sed	struct ttyoutq_block	*to_firstblock;
62188096Sed	struct ttyoutq_block	*to_lastblock;
63188096Sed	unsigned int		to_begin;
64188096Sed	unsigned int		to_end;
65188096Sed	unsigned int		to_nblocks;
66188096Sed	unsigned int		to_quota;
67181905Sed};
68188096Sed#define TTYOUTQ_DATASIZE (256 - sizeof(struct ttyoutq_block *))
69181905Sed
70181905Sed#ifdef _KERNEL
71181905Sed/* Input queue handling routines. */
72183274Sedvoid	ttyinq_setsize(struct ttyinq *ti, struct tty *tp, size_t len);
73183274Sedvoid	ttyinq_free(struct ttyinq *ti);
74183274Sedint	ttyinq_read_uio(struct ttyinq *ti, struct tty *tp, struct uio *uio,
75183274Sed    size_t readlen, size_t flushlen);
76183274Sedsize_t	ttyinq_write(struct ttyinq *ti, const void *buf, size_t len,
77183274Sed    int quote);
78183274Sedint	ttyinq_write_nofrag(struct ttyinq *ti, const void *buf, size_t len,
79183274Sed    int quote);
80183274Sedvoid	ttyinq_canonicalize(struct ttyinq *ti);
81183274Sedsize_t	ttyinq_findchar(struct ttyinq *ti, const char *breakc, size_t maxlen,
82183274Sed    char *lastc);
83183274Sedvoid	ttyinq_flush(struct ttyinq *ti);
84183274Sedint	ttyinq_peekchar(struct ttyinq *ti, char *c, int *quote);
85183274Sedvoid	ttyinq_unputchar(struct ttyinq *ti);
86183274Sedvoid	ttyinq_reprintpos_set(struct ttyinq *ti);
87183274Sedvoid	ttyinq_reprintpos_reset(struct ttyinq *ti);
88181905Sed
89181905Sedstatic __inline size_t
90181905Sedttyinq_getsize(struct ttyinq *ti)
91181905Sed{
92181905Sed	return (ti->ti_nblocks * TTYINQ_DATASIZE);
93181905Sed}
94181905Sed
95181905Sedstatic __inline size_t
96198223Sedttyinq_getallocatedsize(struct ttyinq *ti)
97198223Sed{
98198223Sed
99198223Sed	return (ti->ti_quota * TTYINQ_DATASIZE);
100198223Sed}
101198223Sed
102198223Sedstatic __inline size_t
103181905Sedttyinq_bytesleft(struct ttyinq *ti)
104181905Sed{
105181905Sed	size_t len;
106181905Sed
107181905Sed	/* Make sure the usage never exceeds the length. */
108181905Sed	len = ti->ti_nblocks * TTYINQ_DATASIZE;
109181905Sed	MPASS(len >= ti->ti_end);
110181905Sed
111181905Sed	return (len - ti->ti_end);
112181905Sed}
113181905Sed
114181905Sedstatic __inline size_t
115181905Sedttyinq_bytescanonicalized(struct ttyinq *ti)
116181905Sed{
117181905Sed	MPASS(ti->ti_begin <= ti->ti_linestart);
118181905Sed
119181905Sed	return (ti->ti_linestart - ti->ti_begin);
120181905Sed}
121181905Sed
122181905Sedstatic __inline size_t
123181905Sedttyinq_bytesline(struct ttyinq *ti)
124181905Sed{
125181905Sed	MPASS(ti->ti_linestart <= ti->ti_end);
126181905Sed
127181905Sed	return (ti->ti_end - ti->ti_linestart);
128181905Sed}
129181905Sed
130181905Sed/* Input buffer iteration. */
131183274Sedtypedef void ttyinq_line_iterator_t(void *data, char c, int flags);
132183274Sedvoid	ttyinq_line_iterate_from_linestart(struct ttyinq *ti,
133183274Sed    ttyinq_line_iterator_t *iterator, void *data);
134183274Sedvoid	ttyinq_line_iterate_from_reprintpos(struct ttyinq *ti,
135183274Sed    ttyinq_line_iterator_t *iterator, void *data);
136181905Sed
137181905Sed/* Output queue handling routines. */
138183274Sedvoid	ttyoutq_flush(struct ttyoutq *to);
139183274Sedvoid	ttyoutq_setsize(struct ttyoutq *to, struct tty *tp, size_t len);
140183274Sedvoid	ttyoutq_free(struct ttyoutq *to);
141183274Sedsize_t	ttyoutq_read(struct ttyoutq *to, void *buf, size_t len);
142183274Sedint	ttyoutq_read_uio(struct ttyoutq *to, struct tty *tp, struct uio *uio);
143183274Sedsize_t	ttyoutq_write(struct ttyoutq *to, const void *buf, size_t len);
144183274Sedint	ttyoutq_write_nofrag(struct ttyoutq *to, const void *buf, size_t len);
145181905Sed
146181905Sedstatic __inline size_t
147181905Sedttyoutq_getsize(struct ttyoutq *to)
148181905Sed{
149181905Sed	return (to->to_nblocks * TTYOUTQ_DATASIZE);
150181905Sed}
151181905Sed
152181905Sedstatic __inline size_t
153198223Sedttyoutq_getallocatedsize(struct ttyoutq *to)
154198223Sed{
155198223Sed
156198223Sed	return (to->to_quota * TTYOUTQ_DATASIZE);
157198223Sed}
158198223Sed
159198223Sedstatic __inline size_t
160181905Sedttyoutq_bytesleft(struct ttyoutq *to)
161181905Sed{
162181905Sed	size_t len;
163181905Sed
164181905Sed	/* Make sure the usage never exceeds the length. */
165181905Sed	len = to->to_nblocks * TTYOUTQ_DATASIZE;
166181905Sed	MPASS(len >= to->to_end);
167181905Sed
168181905Sed	return (len - to->to_end);
169181905Sed}
170181905Sed
171181905Sedstatic __inline size_t
172181905Sedttyoutq_bytesused(struct ttyoutq *to)
173181905Sed{
174181905Sed	return (to->to_end - to->to_begin);
175181905Sed}
176181905Sed#endif /* _KERNEL */
177181905Sed
178181905Sed#endif /* !_SYS_TTYQUEUE_H_ */
179