root/drivers/tty/tty_port.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tty_port_default_receive_buf
  2. tty_port_default_wakeup
  3. tty_port_init
  4. tty_port_link_device
  5. tty_port_register_device
  6. tty_port_register_device_attr
  7. tty_port_register_device_attr_serdev
  8. tty_port_register_device_serdev
  9. tty_port_unregister_device
  10. tty_port_alloc_xmit_buf
  11. tty_port_free_xmit_buf
  12. tty_port_destroy
  13. tty_port_destructor
  14. tty_port_put
  15. tty_port_tty_get
  16. tty_port_tty_set
  17. tty_port_shutdown
  18. tty_port_hangup
  19. tty_port_tty_hangup
  20. tty_port_tty_wakeup
  21. tty_port_carrier_raised
  22. tty_port_raise_dtr_rts
  23. tty_port_lower_dtr_rts
  24. tty_port_block_til_ready
  25. tty_port_drain_delay
  26. tty_port_close_start
  27. tty_port_close_end
  28. tty_port_close
  29. tty_port_install
  30. tty_port_open

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

/* [<][>][^][v][top][bottom][index][help] */