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