TTY Port

The TTY drivers are advised to usestructtty_port helpers as much as possible.If the drivers implementtty_port.ops.activate() andtty_port.ops.shutdown(), they can usetty_port_open(),tty_port_close(), andtty_port_hangup() in respectivetty_struct.ops hooks.

The reference and details are contained in theTTY Port Reference andTTYPort Operations Reference sections at the bottom.

TTY Port Functions

Init & Destroy

voidtty_port_init(structtty_port*port)

initialize tty_port

Parameters

structtty_port*port

tty_port to initialize

Description

Initializes the state ofstructtty_port. When a port was initialized usingthis function, one has to destroy the port bytty_port_destroy(). Eitherindirectly by usingtty_port refcounting (tty_port_put()) or directly ifrefcounting is not used.

voidtty_port_destroy(structtty_port*port)

destroy inited port

Parameters

structtty_port*port

tty port to be destroyed

Description

When a port was initialized usingtty_port_init(), one has to destroy theport by this function. Either indirectly by usingtty_port refcounting(tty_port_put()) or directly if refcounting is not used.

voidtty_port_put(structtty_port*port)

drop a reference to tty_port

Parameters

structtty_port*port

port to drop a reference of (can be NULL)

Description

The final put will destroy and free up theport usingport->ops->destruct() hook, or usingkfree() if not provided.

Open/Close/Hangup Helpers

voidtty_port_shutdown(structtty_port*port,structtty_struct*tty)

internal helper to shutdown the device

Parameters

structtty_port*port

tty port to be shut down

structtty_struct*tty

the associated tty

Description

It is used bytty_port_hangup() andtty_port_close(). Its task is toshutdown the device if it was initialized (note consoles remainfunctioning). It lowers DTR/RTS (iftty has HUPCL set) and invokesport->ops->shutdown().

voidtty_port_hangup(structtty_port*port)

hangup helper

Parameters

structtty_port*port

tty port

Description

Perform port level tty hangup flag and count changes. Drop the ttyreference.

Caller holds tty lock.

inttty_port_block_til_ready(structtty_port*port,structtty_struct*tty,structfile*filp)

Waiting logic for tty open

Parameters

structtty_port*port

the tty port being opened

structtty_struct*tty

the tty device being bound

structfile*filp

the file pointer of the opener orNULL

Description

Implement the core POSIX/SuS tty behaviour when opening a tty device.Handles:

  • hangup (both before and during)

  • non blocking open

  • rts/dtr/dcd

  • signals

  • port flags and counts

The passedport must implement theport->ops->carrier_raised method if itcan do carrier detect and theport->ops->dtr_rts method if it supportssoftware management of these lines. Note that the dtr/rts raise is done eachiteration as a hangup may have previously dropped them while we wait.

Caller holds tty lock.

Note

May drop and reacquire tty lock when blocking, sotty andport mayhave changed state (eg., may have been hung up).

inttty_port_close_start(structtty_port*port,structtty_struct*tty,structfile*filp)

helper for tty->ops->close, part 1/2

Parameters

structtty_port*port

tty_port of the device

structtty_struct*tty

tty being closed

structfile*filp

passed file pointer

Description

Decrements and checks open count. Flushes the port if this is the lastclose. That means, dropping the data from the outpu buffer on the device andwaiting for sending logic to finish. The rest of close handling is performedintty_port_close_end().

Locking: Caller holds tty lock.

Return

1 if this is the last close, otherwise 0

voidtty_port_close_end(structtty_port*port,structtty_struct*tty)

helper for tty->ops->close, part 2/2

Parameters

structtty_port*port

tty_port of the device

structtty_struct*tty

tty being closed

Description

This is a continuation of the first part:tty_port_close_start(). Thisshould be called after turning off the device. It flushes the data from theline discipline and delays the close byport->close_delay.

Locking: Caller holds tty lock.

voidtty_port_close(structtty_port*port,structtty_struct*tty,structfile*filp)

generic tty->ops->close handler

Parameters

structtty_port*port

tty_port of the device

structtty_struct*tty

tty being closed

structfile*filp

passed file pointer

Description

It is a generic helper to be used in driver’stty->ops->close. It wraps asequence oftty_port_close_start(),tty_port_shutdown(), andtty_port_close_end(). The latter two are called only if this is the lastclose. See the respective functions for the details.

Locking: Caller holds tty lock

inttty_port_install(structtty_port*port,structtty_driver*driver,structtty_struct*tty)

generic tty->ops->install handler

Parameters

structtty_port*port

tty_port of the device

structtty_driver*driver

tty_driver for this device

structtty_struct*tty

tty to be installed

Description

It is the same astty_standard_install() except the providedport is linkedto a concrete tty specified bytty. Use this ortty_port_register_device()(or both). Calltty_port_link_device() as a last resort.

inttty_port_open(structtty_port*port,structtty_struct*tty,structfile*filp)

generic tty->ops->open handler

Parameters

structtty_port*port

tty_port of the device

structtty_struct*tty

tty to be opened

structfile*filp

passed file pointer

Description

It is a generic helper to be used in driver’stty->ops->open. It activatesthe devices usingport->ops->activate if not active already. And waits forthe device to be ready usingtty_port_block_til_ready() (e.g. raisesDTR/CTS and waits for carrier).

Note thatport->ops->shutdown is not called whenport->ops->activatereturns an error (on the contrary,tty->ops->close is).

Locking: Caller holds tty lock.

Note

may drop and reacquire tty lock (intty_port_block_til_ready()) sotty andport may have changed state (eg., may be hung up now).

TTY Refcounting

structtty_struct*tty_port_tty_get(structtty_port*port)

get a tty reference

Parameters

structtty_port*port

tty port

Description

Return a refcount protected tty instance orNULL if the port is notassociated with a tty (eg due to close or hangup).

voidtty_port_tty_set(structtty_port*port,structtty_struct*tty)

set the tty of a port

Parameters

structtty_port*port

tty port

structtty_struct*tty

the tty

Description

Associate the port and tty pair. Manages any internal refcounts. PassNULLto deassociate a port.

TTY Helpers

voidtty_port_tty_hangup(structtty_port*port,boolcheck_clocal)

helper to hang up a tty asynchronously

Parameters

structtty_port*port

tty port

boolcheck_clocal

hang only ttys withCLOCAL unset?

voidtty_port_tty_vhangup(structtty_port*port)

helper to hang up a tty synchronously

Parameters

structtty_port*port

tty port

voidtty_port_tty_wakeup(structtty_port*port)

helper to wake up a tty

Parameters

structtty_port*port

tty port

Modem Signals

booltty_port_carrier_raised(structtty_port*port)

carrier raised check

Parameters

structtty_port*port

tty port

Description

Wrapper for the carrier detect logic. For the moment this is usedto hide some internal details. This will eventually become entirelyinternal to the tty port.

voidtty_port_raise_dtr_rts(structtty_port*port)

Raise DTR/RTS

Parameters

structtty_port*port

tty port

Description

Wrapper for the DTR/RTS raise logic. For the moment this is used to hidesome internal details. This will eventually become entirely internal to thetty port.

voidtty_port_lower_dtr_rts(structtty_port*port)

Lower DTR/RTS

Parameters

structtty_port*port

tty port

Description

Wrapper for the DTR/RTS raise logic. For the moment this is used to hidesome internal details. This will eventually become entirely internal to thetty port.


TTY Port Reference

structtty_port
  • port level information

Definition:

struct tty_port {    struct tty_bufhead      buf;    struct tty_struct       *tty;    struct tty_struct       *itty;    const struct tty_port_operations *ops;    const struct tty_port_client_operations *client_ops;    spinlock_t lock;    int blocked_open;    int count;    wait_queue_head_t open_wait;    wait_queue_head_t delta_msr_wait;    unsigned long           flags;    unsigned long           iflags;    unsigned char           console:1;    struct mutex            mutex;    struct mutex            buf_mutex;    u8 *xmit_buf;    u8 *xmit_fifo;    unsigned int            close_delay;    unsigned int            closing_wait;    int drain_delay;    struct kref             kref;    void *client_data;};

Members

buf

buffer for this port, locked internally

tty

back pointer tostructtty_struct, valid only if the tty is open. Usetty_port_tty_get() to obtain it (andtty_kref_put() to release).

itty

internal back pointer tostructtty_struct. Avoid this. It should beeliminated in the long term.

ops

tty port operations (like activate, shutdown), seestructtty_port_operations

client_ops

tty port client operations (like receive_buf, write_wakeup).By default, tty_port_default_client_ops is used.

lock

lock protectingtty

blocked_open

# of procs waiting for open intty_port_block_til_ready()

count

usage count

open_wait

open waiters queue (waiting e.g. for a carrier)

delta_msr_wait

modem status change queue (waiting for MSR changes)

flags

user TTY flags (ASYNC_)

iflags

internal flags (TTY_PORT_)

console

when set, the port is a console

mutex

locking, for open, shutdown and other port operations

buf_mutex

xmit_buf alloc lock

xmit_buf

optional xmit buffer used by some drivers

xmit_fifo

optional xmit buffer used by some drivers

close_delay

delay in jiffies to wait when closing the port

closing_wait

delay in jiffies for output to be sent before closing

drain_delay

set to zero if no pure time based drain is needed else set tosize of fifo

kref

references counter. Reaching zero callsops->destruct() if non-NULLor frees the port otherwise.

client_data

pointer to private data, forclient_ops

Description

Each device keeps its own port level information.structtty_port wasintroduced as a common structure for such information. As every TTY deviceshall have a backing tty_port structure, every driver can use these members.

The tty port has a different lifetime to the tty so must be kept apart.In addition be careful as tty -> port mappings are valid for the lifeof the tty object but in many cases port -> tty mappings are valid onlyuntil a hangup so don’t use the wrong path.

Tty port shall be initialized bytty_port_init() and shut down either bytty_port_destroy() (refcounting not used), ortty_port_put() (refcounting).

There is a lot of helpers aroundstructtty_port too. To name the mostsignificant ones:tty_port_open(),tty_port_close() (ortty_port_close_start() andtty_port_close_end() separately if need be), andtty_port_hangup(). These callops->activate() andops->shutdown() asneeded.


TTY Port Operations Reference

structtty_port_operations
  • operations on tty_port

Definition:

struct tty_port_operations {    bool (*carrier_raised)(struct tty_port *port);    void (*dtr_rts)(struct tty_port *port, bool active);    void (*shutdown)(struct tty_port *port);    int (*activate)(struct tty_port *port, struct tty_struct *tty);    void (*destruct)(struct tty_port *port);};

Members

carrier_raised

return true if the carrier is raised onport

dtr_rts

raise the DTR line ifactive is true, otherwise lower DTR

shutdown

called when the last close completes or a hangup finishes IFF theport was initialized. Do not use to free resources. Turn off the deviceonly. Called under the port mutex to serialize againstactivate andshutdown.

activate

called under the port mutex fromtty_port_open(), serialized usingthe port mutex. Supposed to turn on the device.

destruct

called on the final put of a port. Free resources, possibly incl.the port itself.

Description

FIXME: long term getting the tty argumentout of this would be goodfor consoles.