online
  +   ˆl–äY>”TÔD¨ 	Å�rã`S�ÿÃ„h_†I|¥�+ÀÆ ),    /* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_TTY_LDISC_H
#define _LINUX_TTY_LDISC_H

struct tty_struct;

#include <linux/fs.h>
#include <linux/wait.h>
#include <linux/atomic.h>
#include <linux/list.h>
#include <linux/lockdep.h>
#include <linux/seq_file.h>

/*
 * the semaphore definition
 */
struct ld_semaphore {
	atomic_long_t		count;
	raw_spinlock_t		wait_lock;
	unsigned int		wait_readers;
	struct list_head	read_wait;
	struct list_head	write_wait;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
	struct lockdep_map	dep_map;
#endif
};

void __init_ldsem(struct ld_semaphore *sem, const char *name,
			 struct lock_class_key *key);

#define init_ldsem(sem)						\
do {								\
	static struct lock_class_key __key;			\
								\
	__init_ldsem((sem), #sem, &__key);			\
} while (0)


int ldsem_down_read(struct ld_semaphore *sem, long timeout);
int ldsem_down_read_trylock(struct ld_semaphore *sem);
int ldsem_down_write(struct ld_semaphore *sem, long timeout);
int ldsem_down_write_trylock(struct ld_semaphore *sem);
void ldsem_up_read(struct ld_semaphore *sem);
void ldsem_up_write(struct ld_semaphore *sem);

#ifdef CONFIG_DEBUG_LOCK_ALLOC
int ldsem_down_read_nested(struct ld_semaphore *sem, int subclass,
		long timeout);
int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass,
		long timeout);
#else
# define ldsem_down_read_nested(sem, subclass, timeout)		\
		ldsem_down_read(sem, timeout)
# define ldsem_down_write_nested(sem, subclass, timeout)	\
		ldsem_down_write(sem, timeout)
#endif

/**
 * struct tty_ldisc_ops - ldisc operations
 *
 * @name: name of this ldisc rendered in /proc/tty/ldiscs
 * @num: ``N_*`` number (%N_TTY, %N_HDLC, ...) reserved to this ldisc
 *
 * @open: [TTY] ``int ()(struct tty_struct *tty)``
 *
 *	This function is called when the line discipline is associated with the
 *	@tty. No other call into the line discipline for this tty will occur
 *	until it completes successfully. It should initialize any state needed
 *	by the ldisc, and set @tty->receive_room to the maximum amount of data
 *	the line discipline is willing to accept from the driver with a single
 *	call to @receive_buf(). Returning an error will prevent the ldisc from
 *	being attached.
 *
 *	Optional. Can sleep.
 *
 * @close: [TTY] ``void ()(struct tty_struct *tty)``
 *
 *	This function is called when the line discipline is being shutdown,
 *	either because the @tty is being closed or because the @tty is being
 *	changed to use a new line discipline. At the point of execution no
 *	further users will enter the ldisc code for this tty.
 *
 *	Optional. Can sleep.
 *
 * @flush_buffer: [TTY] ``void ()(struct tty_struct *tty)``
 *
 *	This function instructs the line discipline to clear its buffers of any
 *	input characters it may have queued to be delivered to the user mode
 *	process. It may be called at any point between open and close.
 *
 *	Optional.
 *
 * @read: [TTY] ``ssize_t ()(struct tty_struct *tty, struct file *file, u8 *buf,
 *		size_t nr)``
 *
 *	This function is called when the user requests to read from the @tty.
 *	The line discipline will return whatever characters it has buffered up
 *	for the user. If this function is not defined, the user will receive
 *	an %EIO error. Multiple read calls may occur in parallel and the ldisc
 *	must deal with serialization issues.
 *
 *	Optional: %EIO unless provided. Can sleep.
 *
 * @write: [TTY] ``ssize_t ()(struct tty_struct *tty, struct file *file,
 *		 const u8 *buf, size_t nr)``
 *
 *	This function is called when the user requests to write to the @tty.
 *	The line discipline will deliver the characters to the low-level tty
 *	device for transmission, optionally performing some processing on the
 *	characters first. If this function is not defined, the user will
 *	receive an %EIO error.
 *
 *	Optional: %EIO unless provided. Can sleep.
 *
 * @ioctl: [TTY] ``int ()(struct tty_struct *tty, unsigned int cmd,
 *		unsigned long arg)``
 *
 *	This function is called when the user requests an ioctl which is not
 *	handled by the tt