XenevaOS
Loading...
Searching...
No Matches
tty_port.h
Go to the documentation of this file.
1#ifndef _LINUX_TTY_PORT_H
2#define _LINUX_TTY_PORT_H
3
4/*
5 * DCL <linux/tty_port.h> -- port-level state shared by every tty driver.
6 *
7 * Ported from mainline v7.2. A tty_port outlives the tty that opens it: the
8 * port is the device, the tty is one open of it, which is why the two have
9 * separate reference counts (port->kref for the port, tty->kref for the tty)
10 * and why port->tty can go NULL on a hangup while the port stays.
11 *
12 * The parts that matter most to the 8250 port:
13 *
14 * buf -- the flip buffer head. uart_handle_rx_char() writes into it
15 * from interrupt context; tty_flip_buffer_push() commits.
16 * xmit_buf / xmit_fifo
17 * -- the transmit ring. serial_core.c allocates xmit_buf on
18 * demand (serial_core.c:262) and binds it to xmit_fifo with
19 * kfifo_init(); uart_write() pushes, the driver's start_tx
20 * drains, and WAKEUP_CHARS is the threshold for telling the
21 * tty there is room again.
22 * iflags -- TTY_PORT_* bits, read with test_bit() throughout.
23 * client_ops -- how buffered input reaches the ldisc. This is the indirection
24 * tty_buffer.c calls through (port->client_ops->receive_buf),
25 * added upstream so that a tty port can be fed without a tty
26 * (serdev, and the console). tty_port.h:49 names the default.
27 *
28 * The tty_port_tty guard at the bottom of this file: mainline writes it with
29 * __DEFINE_UNLOCK_GUARD and reads the guarded pointer back through
30 * scoped_tty(). It was deferred on the grounds that inventing acquire/release
31 * semantics without a call site would mean guessing rather than reading them
32 * off mainline -- and then 8250_port.c arrived in stage 3 with the call site
33 * at serial8250_update_uartclk(), line 2608. So it is ported from that one
34 * use, which is how it should have been written the first time.
35 */
36
37#include <linux/kfifo.h>
38#include <linux/kref.h>
39#include <linux/mutex.h>
40#include <linux/tty_buffer.h>
41#include <linux/tty_driver.h>
42#include <linux/wait.h>
43
44struct attribute_group;
45struct tty_port;
46struct tty_struct;
47
49 bool (*carrier_raised)(struct tty_port* port);
50 void (*dtr_rts)(struct tty_port* port, bool active);
51 void (*shutdown)(struct tty_port* port);
52 int (*activate)(struct tty_port* port, struct tty_struct* tty);
53 void (*destruct)(struct tty_port* port);
54};
55
57 size_t (*receive_buf)(struct tty_port* port, const u8* cp,
58 const u8* fp, size_t count);
59 void (*lookahead_buf)(struct tty_port* port, const u8* cp,
60 const u8* fp, size_t count);
61 void (*write_wakeup)(struct tty_port* port);
62};
63
65
66/*
67 * `buf` is a struct tty_bufhead, which itself contains a variable-sized
68 * member (see the note in <linux/tty_buffer.h>), so embedding it anywhere but
69 * the end of tty_port raises the same -Wgnu-variable-sized-type-not-at-end.
70 * It is first here in mainline's layout and the reason is the same as there:
71 * the flip buffer is the part of a port that is allocated, everything after
72 * it is bookkeeping, and uart_add_one_port() walks the port as one block.
73 * Scoped suppression rather than a reordering, for the reason given above.
74 */
75#if defined(__clang__)
76#pragma clang diagnostic push
77#pragma clang diagnostic ignored "-Wgnu-variable-sized-type-not-at-end"
78#endif
103#if defined(__clang__)
104#pragma clang diagnostic pop
105#endif
106
107/* tty_port::iflags bits -- use atomic bit ops */
108#define TTY_PORT_INITIALIZED 0 /* device is initialized */
109#define TTY_PORT_SUSPENDED 1 /* device is suspended */
110#define TTY_PORT_ACTIVE 2 /* device is open */
111
112/*
113 * uart drivers: use the uart_port::status field and the UPSTAT_* defines
114 * for s/w-based flow control steering and carrier detection status
115 */
116#define TTY_PORT_CTS_FLOW 3 /* h/w flow control enabled */
117#define TTY_PORT_CHECK_CD 4 /* carrier detect enabled */
118#define TTY_PORT_KOPENED 5 /* device exclusively opened by kernel */
119
120void tty_port_init(struct tty_port* port);
121void tty_port_link_wq(struct tty_port* port, struct workqueue_struct* flip_wq);
122void tty_port_link_device(struct tty_port* port, struct tty_driver* driver,
123 unsigned index);
125 struct tty_driver* driver, unsigned index,
126 struct device* device);
128 struct tty_driver* driver, unsigned index,
129 struct device* device, void* drvdata,
130 const struct attribute_group** attr_grp);
132 struct tty_driver* driver, unsigned index,
133 struct device* host, struct device* parent, void* drvdata,
134 const struct attribute_group** attr_grp);
136 struct tty_driver* driver, unsigned index);
139void tty_port_destroy(struct tty_port* port);
140void tty_port_put(struct tty_port* port);
141
142static inline struct tty_port* tty_port_get(struct tty_port* port)
143{
144 if (port && kref_get_unless_zero(&port->kref))
145 return port;
146 return NULL;
147}
148
149/*
150 * Never overwrite the workqueue set by tty_port_link_wq().
151 * No effect when %TTY_DRIVER_NO_WORKQUEUE is set, as driver->flip_wq is
152 * %NULL.
153 */
154static inline void tty_port_link_driver_wq(struct tty_port* port,
155 struct tty_driver* driver)
156{
157 if (!port->buf.flip_wq)
158 tty_port_link_wq(port, driver->flip_wq);
159}
160
161/* If the cts flow control is enabled, return true. */
162static inline bool tty_port_cts_enabled(const struct tty_port* port)
163{
164 return test_bit(TTY_PORT_CTS_FLOW, &port->iflags);
165}
166
167static inline void tty_port_set_cts_flow(struct tty_port* port, bool val)
168{
169 assign_bit(TTY_PORT_CTS_FLOW, &port->iflags, val);
170}
171
172static inline bool tty_port_active(const struct tty_port* port)
173{
174 return test_bit(TTY_PORT_ACTIVE, &port->iflags);
175}
176
177static inline void tty_port_set_active(struct tty_port* port, bool val)
178{
179 assign_bit(TTY_PORT_ACTIVE, &port->iflags, val);
180}
181
182static inline bool tty_port_check_carrier(const struct tty_port* port)
183{
184 return test_bit(TTY_PORT_CHECK_CD, &port->iflags);
185}
186
187static inline void tty_port_set_check_carrier(struct tty_port* port, bool val)
188{
189 assign_bit(TTY_PORT_CHECK_CD, &port->iflags, val);
190}
191
192static inline bool tty_port_suspended(const struct tty_port* port)
193{
194 return test_bit(TTY_PORT_SUSPENDED, &port->iflags);
195}
196
197static inline void tty_port_set_suspended(struct tty_port* port, bool val)
198{
200}
201
202static inline bool tty_port_initialized(const struct tty_port* port)
203{
204 return test_bit(TTY_PORT_INITIALIZED, &port->iflags);
205}
206
207static inline void tty_port_set_initialized(struct tty_port* port, bool val)
208{
210}
211
212static inline bool tty_port_kopened(const struct tty_port* port)
213{
214 return test_bit(TTY_PORT_KOPENED, &port->iflags);
215}
216
217static inline void tty_port_set_kopened(struct tty_port* port, bool val)
218{
219 assign_bit(TTY_PORT_KOPENED, &port->iflags, val);
220}
221
223void tty_port_tty_set(struct tty_port* port, struct tty_struct* tty);
228void __tty_port_tty_hangup(struct tty_port* port, bool check_clocal,
229 bool async);
232 struct file* filp);
234 struct file* filp);
235void tty_port_close_end(struct tty_port* port, struct tty_struct* tty);
236void tty_port_close(struct tty_port* port, struct tty_struct* tty,
237 struct file* filp);
239 struct tty_struct* tty);
240int tty_port_open(struct tty_port* port, struct tty_struct* tty,
241 struct file* filp);
242
243static inline int tty_port_users(struct tty_port* port)
244{
245 return port->count + port->blocked_open;
246}
247
252static inline void tty_port_tty_hangup(struct tty_port* port, bool check_clocal)
253{
254 __tty_port_tty_hangup(port, check_clocal, true);
255}
256
260static inline void tty_port_tty_vhangup(struct tty_port* port)
261{
262 __tty_port_tty_hangup(port, false, false);
263}
264
265void tty_kref_put(struct tty_struct* tty);
266
267
268/*
269 * Guard class `tty_port_tty` and scoped_tty().
270 *
271 * mainline spells the definitions
272 *
273 * __DEFINE_UNLOCK_GUARD(tty_port_tty, struct tty_struct, tty_kref_put(_T->lock));
274 * static inline class_tty_port_tty_t class_tty_port_tty_constructor(struct tty_port *tport)
275 * { return (class_tty_port_tty_t){ .lock = tty_port_tty_get(tport) }; }
276 * #define scoped_tty() ((struct tty_struct *)(__guard_ptr(tty_port_tty)(&scope)))
277 *
278 * DCL spells them on its own machinery because __DEFINE_UNLOCK_GUARD is not
279 * ported (see <linux/cleanup.h> for why the DEFINE_* family is only partly
280 * here), and because the acquire argument is a *tty_port* while the guarded
281 * object is a *tty* -- mainline's constructor function exists precisely to
282 * cross that type boundary, so it cannot be expressed as DEFINE_LOCK_GUARD_1,
283 * whose constructor takes the guarded type.
284 *
285 * The one real adaptation is scoped_tty(): mainline reads the variable the
286 * guard macro named `scope`, DCL's scoped_guard() names it `_dclg`, so the
287 * macro expands to `_dclg.lock`. Everything else -- who takes a reference
288 * (tty_port_tty_get) and who drops it (tty_kref_put), and that the release is
289 * skipped when the port holds no tty, so a NULL guard must not call kref_put
290 * on NULL -- is read straight off the two mainline lines above.
291 *
292 * Semantics worth stating, since it is easy to get wrong in a driver: the
293 * guard holds one *reference*, not a borrowed pointer, so the tty cannot
294 * disappear while scoped_guard()'s body runs, and leaving the scope drops that
295 * reference. That is exactly what 8250_port.c:2608 wants -- it goes on to
296 * take termios_rwsem on the tty it just looked up.
297 */
298typedef struct {
301
302static inline void dclg_tty_port_tty_release(dclg_tty_port_tty* g)
303{
304 struct tty_struct* _T = g->lock;
305 if (_T) {
306 tty_kref_put(_T);
307 }
308}
309
310static inline dclg_tty_port_tty dclg_tty_port_tty_ctor(struct tty_port* tport)
311{
313 g.lock = tty_port_tty_get(tport);
314 return g;
315}
316
317/*
318 * The guarded tty of the enclosing scoped_guard(tty_port_tty, ...).
319 *
320 * Only valid inside that block -- it names the variable scoped_guard()
321 * created, so there is no hidden second lookup and no way to outlive it
322 * without a compile error.
323 */
324#define scoped_tty() ((struct tty_struct*)(_dclg.lock))
325
326#endif /* __LINUX_TTY_PORT_H__ */
#define bool
Definition stdbool.h:35
uint64_t size_t
Definition stdint.h:104
#define index(str, chr)
Definition string.h:66
#define NULL
Definition actypes.h:561
#define assign_bit(nr, addr, val)
Definition bitops.h:237
#define test_bit(nr, addr)
Definition bitops.h:124
struct kobject * parent
Definition kobject.h:91
uint8_t u8
Definition kernel.h:14
int spinlock_t
Definition kernel.h:44
Definition sysfs.h:33
Definition tty_port.h:298
struct tty_struct * lock
Definition tty_port.h:299
Definition fs.h:255
Definition fs.h:142
Definition kref.h:44
Definition mutex.h:59
Definition tty_buffer.h:80
struct workqueue_struct * flip_wq
Definition tty_buffer.h:82
Definition tty_driver.h:122
struct workqueue_struct * flip_wq
Definition tty_driver.h:138
Definition tty_port.h:56
void(* lookahead_buf)(struct tty_port *port, const u8 *cp, const u8 *fp, size_t count)
Definition tty_port.h:59
size_t(* receive_buf)(struct tty_port *port, const u8 *cp, const u8 *fp, size_t count)
Definition tty_port.h:57
void(* write_wakeup)(struct tty_port *port)
Definition tty_port.h:61
Definition tty_port.h:48
void(* shutdown)(struct tty_port *port)
Definition tty_port.h:51
void(* dtr_rts)(struct tty_port *port, bool active)
Definition tty_port.h:50
int(* activate)(struct tty_port *port, struct tty_struct *tty)
Definition tty_port.h:52
bool(* carrier_raised)(struct tty_port *port)
Definition tty_port.h:49
void(* destruct)(struct tty_port *port)
Definition tty_port.h:53
Definition tty_port.h:79
struct tty_struct * itty
Definition tty_port.h:82
unsigned long flags
Definition tty_port.h:90
struct tty_struct * tty
Definition tty_port.h:81
struct tty_bufhead buf
Definition tty_port.h:80
unsigned int close_delay
Definition tty_port.h:97
struct kref kref
Definition tty_port.h:100
spinlock_t lock
Definition tty_port.h:85
int drain_delay
Definition tty_port.h:99
unsigned int closing_wait
Definition tty_port.h:98
const struct tty_port_client_operations * client_ops
Definition tty_port.h:84
int blocked_open
Definition tty_port.h:86
struct mutex buf_mutex
Definition tty_port.h:94
wait_queue_head_t open_wait
Definition tty_port.h:88
u8 * xmit_buf
Definition tty_port.h:95
unsigned long iflags
Definition tty_port.h:91
void * client_data
Definition tty_port.h:101
wait_queue_head_t delta_msr_wait
Definition tty_port.h:89
const struct tty_port_operations * ops
Definition tty_port.h:83
unsigned char console
Definition tty_port.h:92
DECLARE_KFIFO_PTR(xmit_fifo, u8)
int count
Definition tty_port.h:87
Definition tty.h:203
struct tty_driver * driver
Definition tty.h:207
struct tty_port * port
Definition tty.h:208
Definition wait.h:75
Definition workqueue.h:50
void tty_kref_put(struct tty_struct *tty)
int tty_port_block_til_ready(struct tty_port *port, struct tty_struct *tty, struct file *filp)
void tty_port_tty_wakeup(struct tty_port *port)
struct device * tty_port_register_device_attr(struct tty_port *port, struct tty_driver *driver, unsigned index, struct device *device, void *drvdata, const struct attribute_group **attr_grp)
void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
void tty_port_raise_dtr_rts(struct tty_port *port)
#define TTY_PORT_INITIALIZED
Definition tty_port.h:108
#define TTY_PORT_SUSPENDED
Definition tty_port.h:109
void tty_port_hangup(struct tty_port *port)
void tty_port_link_wq(struct tty_port *port, struct workqueue_struct *flip_wq)
#define TTY_PORT_CTS_FLOW
Definition tty_port.h:116
void tty_port_unregister_device(struct tty_port *port, struct tty_driver *driver, unsigned index)
void tty_port_destroy(struct tty_port *port)
void tty_port_close(struct tty_port *port, struct tty_struct *tty, struct file *filp)
void tty_port_free_xmit_buf(struct tty_port *port)
#define TTY_PORT_KOPENED
Definition tty_port.h:118
void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
const struct tty_port_client_operations tty_port_default_client_ops
int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp)
struct tty_struct * tty_port_tty_get(struct tty_port *port)
#define TTY_PORT_CHECK_CD
Definition tty_port.h:117
void tty_port_link_device(struct tty_port *port, struct tty_driver *driver, unsigned index)
void tty_port_lower_dtr_rts(struct tty_port *port)
void tty_port_init(struct tty_port *port)
void tty_port_put(struct tty_port *port)
int tty_port_install(struct tty_port *port, struct tty_driver *driver, struct tty_struct *tty)
#define TTY_PORT_ACTIVE
Definition tty_port.h:110
struct device * tty_port_register_device(struct tty_port *port, struct tty_driver *driver, unsigned index, struct device *device)
int tty_port_alloc_xmit_buf(struct tty_port *port)
bool tty_port_carrier_raised(struct tty_port *port)
void __tty_port_tty_hangup(struct tty_port *port, bool check_clocal, bool async)
int tty_port_open(struct tty_port *port, struct tty_struct *tty, struct file *filp)
struct device * tty_port_register_device_attr_serdev(struct tty_port *port, struct tty_driver *driver, unsigned index, struct device *host, struct device *parent, void *drvdata, const struct attribute_group **attr_grp)