^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Tty port functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/tty_driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/serdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static int tty_port_default_receive_buf(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) const unsigned char *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) const unsigned char *f, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct tty_ldisc *disc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) tty = READ_ONCE(port->itty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) if (!tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) disc = tty_ldisc_ref(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) if (!disc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) ret = tty_ldisc_receive_buf(disc, p, (char *)f, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) tty_ldisc_deref(disc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static void tty_port_default_wakeup(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct tty_struct *tty = tty_port_tty_get(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (tty) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) tty_wakeup(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) const struct tty_port_client_operations tty_port_default_client_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .receive_buf = tty_port_default_receive_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .write_wakeup = tty_port_default_wakeup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) EXPORT_SYMBOL_GPL(tty_port_default_client_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) void tty_port_init(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) memset(port, 0, sizeof(*port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) tty_buffer_init(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) init_waitqueue_head(&port->open_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) init_waitqueue_head(&port->delta_msr_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) mutex_init(&port->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) mutex_init(&port->buf_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) spin_lock_init(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) port->close_delay = (50 * HZ) / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) port->closing_wait = (3000 * HZ) / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) port->client_ops = &tty_port_default_client_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) kref_init(&port->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) EXPORT_SYMBOL(tty_port_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * tty_port_link_device - link tty and tty_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * @port: tty_port of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * @driver: tty_driver for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * @index: index of the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * Provide the tty layer with a link from a tty (specified by @index) to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * tty_port (@port). Use this only if neither tty_port_register_device nor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * tty_port_install is used in the driver. If used, this has to be called before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * tty_register_driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) void tty_port_link_device(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct tty_driver *driver, unsigned index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (WARN_ON(index >= driver->num))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) driver->ports[index] = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) EXPORT_SYMBOL_GPL(tty_port_link_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * tty_port_register_device - register tty device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * @port: tty_port of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @driver: tty_driver for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @index: index of the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * @device: parent if exists, otherwise NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * It is the same as tty_register_device except the provided @port is linked to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * a concrete tty specified by @index. Use this or tty_port_install (or both).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * Call tty_port_link_device as a last resort.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct device *tty_port_register_device(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct tty_driver *driver, unsigned index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return tty_port_register_device_attr(port, driver, index, device, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) EXPORT_SYMBOL_GPL(tty_port_register_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * tty_port_register_device_attr - register tty device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * @port: tty_port of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * @driver: tty_driver for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * @index: index of the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * @device: parent if exists, otherwise NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * @drvdata: Driver data to be set to device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * @attr_grp: Attribute group to be set on device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * It is the same as tty_register_device_attr except the provided @port is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * linked to a concrete tty specified by @index. Use this or tty_port_install
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * (or both). Call tty_port_link_device as a last resort.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct device *tty_port_register_device_attr(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct tty_driver *driver, unsigned index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct device *device, void *drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) const struct attribute_group **attr_grp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) tty_port_link_device(port, driver, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return tty_register_device_attr(driver, index, device, drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) attr_grp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) EXPORT_SYMBOL_GPL(tty_port_register_device_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * tty_port_register_device_attr_serdev - register tty or serdev device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * @port: tty_port of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * @driver: tty_driver for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * @index: index of the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * @device: parent if exists, otherwise NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * @drvdata: driver data for the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * @attr_grp: attribute group for the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * Register a serdev or tty device depending on if the parent device has any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * defined serdev clients or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct device *tty_port_register_device_attr_serdev(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct tty_driver *driver, unsigned index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct device *device, void *drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) const struct attribute_group **attr_grp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) tty_port_link_device(port, driver, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) dev = serdev_tty_port_register(port, device, driver, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (PTR_ERR(dev) != -ENODEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* Skip creating cdev if we registered a serdev device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return tty_register_device_attr(driver, index, device, drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) attr_grp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) EXPORT_SYMBOL_GPL(tty_port_register_device_attr_serdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * tty_port_register_device_serdev - register tty or serdev device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * @port: tty_port of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * @driver: tty_driver for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * @index: index of the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * @device: parent if exists, otherwise NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * Register a serdev or tty device depending on if the parent device has any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * defined serdev clients or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct device *tty_port_register_device_serdev(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct tty_driver *driver, unsigned index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return tty_port_register_device_attr_serdev(port, driver, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) device, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) EXPORT_SYMBOL_GPL(tty_port_register_device_serdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * tty_port_unregister_device - deregister a tty or serdev device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * @port: tty_port of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * @driver: tty_driver for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * @index: index of the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * If a tty or serdev device is registered with a call to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * tty_port_register_device_serdev() then this function must be called when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * the device is gone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) void tty_port_unregister_device(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct tty_driver *driver, unsigned index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ret = serdev_tty_port_unregister(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) tty_unregister_device(driver, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) EXPORT_SYMBOL_GPL(tty_port_unregister_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int tty_port_alloc_xmit_buf(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* We may sleep in get_zeroed_page() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) mutex_lock(&port->buf_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (port->xmit_buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) mutex_unlock(&port->buf_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (port->xmit_buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) void tty_port_free_xmit_buf(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) mutex_lock(&port->buf_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (port->xmit_buf != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) free_page((unsigned long)port->xmit_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) port->xmit_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) mutex_unlock(&port->buf_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) EXPORT_SYMBOL(tty_port_free_xmit_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * tty_port_destroy -- destroy inited port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * @port: tty port to be destroyed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * When a port was initialized using tty_port_init, one has to destroy the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * port by this function. Either indirectly by using tty_port refcounting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * (tty_port_put) or directly if refcounting is not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) void tty_port_destroy(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) tty_buffer_cancel_work(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) tty_buffer_free_all(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) EXPORT_SYMBOL(tty_port_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static void tty_port_destructor(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct tty_port *port = container_of(kref, struct tty_port, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* check if last port ref was dropped before tty release */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (WARN_ON(port->itty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (port->xmit_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) free_page((unsigned long)port->xmit_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) tty_port_destroy(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (port->ops && port->ops->destruct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) port->ops->destruct(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) kfree(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) void tty_port_put(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) kref_put(&port->kref, tty_port_destructor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) EXPORT_SYMBOL(tty_port_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * tty_port_tty_get - get a tty reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * @port: tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * Return a refcount protected tty instance or NULL if the port is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * associated with a tty (eg due to close or hangup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct tty_struct *tty_port_tty_get(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) tty = tty_kref_get(port->tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) EXPORT_SYMBOL(tty_port_tty_get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * tty_port_tty_set - set the tty of a port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * @port: tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * @tty: the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * Associate the port and tty pair. Manages any internal refcounts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * Pass NULL to deassociate a port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) tty_kref_put(port->tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) port->tty = tty_kref_get(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) EXPORT_SYMBOL(tty_port_tty_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) mutex_lock(&port->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (port->console)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (tty_port_initialized(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) tty_port_set_initialized(port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * Drop DTR/RTS if HUPCL is set. This causes any attached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * modem to hang up the line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (tty && C_HUPCL(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) tty_port_lower_dtr_rts(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (port->ops->shutdown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) port->ops->shutdown(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) mutex_unlock(&port->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * tty_port_hangup - hangup helper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * @port: tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * Perform port level tty hangup flag and count changes. Drop the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * Caller holds tty lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) void tty_port_hangup(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) port->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) tty = port->tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) set_bit(TTY_IO_ERROR, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) port->tty = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) tty_port_set_active(port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) tty_port_shutdown(port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) wake_up_interruptible(&port->open_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) wake_up_interruptible(&port->delta_msr_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) EXPORT_SYMBOL(tty_port_hangup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * tty_port_tty_hangup - helper to hang up a tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * @port: tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * @check_clocal: hang only ttys with CLOCAL unset?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) void tty_port_tty_hangup(struct tty_port *port, bool check_clocal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct tty_struct *tty = tty_port_tty_get(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (tty && (!check_clocal || !C_CLOCAL(tty)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) tty_hangup(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) EXPORT_SYMBOL_GPL(tty_port_tty_hangup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * tty_port_tty_wakeup - helper to wake up a tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * @port: tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) void tty_port_tty_wakeup(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) port->client_ops->write_wakeup(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) EXPORT_SYMBOL_GPL(tty_port_tty_wakeup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * tty_port_carrier_raised - carrier raised check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * @port: tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * Wrapper for the carrier detect logic. For the moment this is used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * to hide some internal details. This will eventually become entirely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * internal to the tty port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) int tty_port_carrier_raised(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (port->ops->carrier_raised == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return port->ops->carrier_raised(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) EXPORT_SYMBOL(tty_port_carrier_raised);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * tty_port_raise_dtr_rts - Raise DTR/RTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * @port: tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * Wrapper for the DTR/RTS raise logic. For the moment this is used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * to hide some internal details. This will eventually become entirely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * internal to the tty port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) void tty_port_raise_dtr_rts(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (port->ops->dtr_rts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) port->ops->dtr_rts(port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) EXPORT_SYMBOL(tty_port_raise_dtr_rts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * tty_port_lower_dtr_rts - Lower DTR/RTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * @port: tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * Wrapper for the DTR/RTS raise logic. For the moment this is used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * to hide some internal details. This will eventually become entirely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * internal to the tty port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) void tty_port_lower_dtr_rts(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (port->ops->dtr_rts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) port->ops->dtr_rts(port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) EXPORT_SYMBOL(tty_port_lower_dtr_rts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * tty_port_block_til_ready - Waiting logic for tty open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * @port: the tty port being opened
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * @tty: the tty device being bound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * @filp: the file pointer of the opener or NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * Implement the core POSIX/SuS tty behaviour when opening a tty device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * Handles:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * - hangup (both before and during)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * - non blocking open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * - rts/dtr/dcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * - signals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * - port flags and counts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * The passed tty_port must implement the carrier_raised method if it can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * do carrier detect and the dtr_rts method if it supports software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * management of these lines. Note that the dtr/rts raise is done each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * iteration as a hangup may have previously dropped them while we wait.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * Caller holds tty lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * NB: May drop and reacquire tty lock when blocking, so tty and tty_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * may have changed state (eg., may have been hung up).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) int tty_port_block_til_ready(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct tty_struct *tty, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) int do_clocal = 0, retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) DEFINE_WAIT(wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) /* if non-blocking mode is set we can pass directly to open unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) the port has just hung up or is in another error state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (tty_io_error(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) tty_port_set_active(port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (filp == NULL || (filp->f_flags & O_NONBLOCK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /* Indicate we are open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (C_BAUD(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) tty_port_raise_dtr_rts(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) tty_port_set_active(port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (C_CLOCAL(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) do_clocal = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* Block waiting until we can proceed. We may need to wait for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) carrier, but we must also wait for any close that is in progress
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) before the next open may complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* The port lock protects the port counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) port->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) port->blocked_open++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /* Indicate we are open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (C_BAUD(tty) && tty_port_initialized(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) tty_port_raise_dtr_rts(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* Check for a hangup or uninitialised port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) Return accordingly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (tty_hung_up_p(filp) || !tty_port_initialized(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (port->flags & ASYNC_HUP_NOTIFY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) retval = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) retval = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * Probe the carrier. For devices with no carrier detect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * tty_port_carrier_raised will always return true.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * Never ask drivers if CLOCAL is set, this causes troubles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * on some hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (do_clocal || tty_port_carrier_raised(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) retval = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) tty_unlock(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) tty_lock(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) finish_wait(&port->open_wait, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) /* Update counts. A parallel hangup will have set count to zero and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) we must not mess that up further */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (!tty_hung_up_p(filp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) port->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) port->blocked_open--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (retval == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) tty_port_set_active(port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) EXPORT_SYMBOL(tty_port_block_til_ready);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) static void tty_port_drain_delay(struct tty_port *port, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) unsigned int bps = tty_get_baud_rate(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (bps > 1200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) timeout = (HZ * 10 * port->drain_delay) / bps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) timeout = max_t(long, timeout, HZ / 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) timeout = 2 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) schedule_timeout_interruptible(timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /* Caller holds tty lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) int tty_port_close_start(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct tty_struct *tty, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (tty_hung_up_p(filp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (tty->count == 1 && port->count != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) tty_warn(tty, "%s: tty->count = 1 port count = %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) port->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) port->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (--port->count < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) tty_warn(tty, "%s: bad port count (%d)\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) port->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) port->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (port->count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) tty->closing = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (tty_port_initialized(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /* Don't block on a stalled port, just pull the chain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (tty->flow_stopped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) tty_driver_flush_buffer(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) tty_wait_until_sent(tty, port->closing_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (port->drain_delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) tty_port_drain_delay(port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /* Flush the ldisc buffering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) tty_ldisc_flush(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) /* Report to caller this is the last port reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) EXPORT_SYMBOL(tty_port_close_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /* Caller holds tty lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) tty_ldisc_flush(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) tty->closing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (port->blocked_open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (port->close_delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) msleep_interruptible(jiffies_to_msecs(port->close_delay));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) wake_up_interruptible(&port->open_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) tty_port_set_active(port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) EXPORT_SYMBOL(tty_port_close_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * tty_port_close
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * Caller holds tty lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) void tty_port_close(struct tty_port *port, struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (tty_port_close_start(port, tty, filp) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) tty_port_shutdown(port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (!port->console)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) set_bit(TTY_IO_ERROR, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) tty_port_close_end(port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) tty_port_tty_set(port, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) EXPORT_SYMBOL(tty_port_close);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * tty_port_install - generic tty->ops->install handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * @port: tty_port of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * @driver: tty_driver for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * @tty: tty to be installed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * It is the same as tty_standard_install except the provided @port is linked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * to a concrete tty specified by @tty. Use this or tty_port_register_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * (or both). Call tty_port_link_device as a last resort.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) int tty_port_install(struct tty_port *port, struct tty_driver *driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) tty->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return tty_standard_install(driver, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) EXPORT_SYMBOL_GPL(tty_port_install);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * tty_port_open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * Caller holds tty lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * NB: may drop and reacquire tty lock (in tty_port_block_til_ready()) so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) * tty and tty_port may have changed state (eg., may be hung up now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) int tty_port_open(struct tty_port *port, struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) spin_lock_irq(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) ++port->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) spin_unlock_irq(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) tty_port_tty_set(port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * Do the device-specific open only if the hardware isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * already initialized. Serialize open and shutdown using the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * port mutex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) mutex_lock(&port->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (!tty_port_initialized(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) clear_bit(TTY_IO_ERROR, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (port->ops->activate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) int retval = port->ops->activate(port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) mutex_unlock(&port->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) tty_port_set_initialized(port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) mutex_unlock(&port->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) return tty_port_block_til_ready(port, tty, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) EXPORT_SYMBOL(tty_port_open);