lkml.org 
[lkml]   [2009]   [Oct]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[088/136] tty: Add a full port_close function
    2.6.31-stable review patch.  If anyone has any objections, please let us know.

    ------------------
    From: Alan Cox <alan@linux.intel.com>

    commit 7ca0ff9ab3218ec443a7a9ad247e4650373ed41e upstream.

    Now we are extracting out methods for shutdown and the like we can add a
    proper tty_port_close method that knows all the innards of the tty closing
    process and hides the lot from the caller.

    At some point in the future this will be paired with a similar open()
    helper and the drivers can stick to hardware management.

    Signed-off-by: Alan Cox <alan@linux.intel.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    drivers/char/tty_port.c | 29 +++++++++++++++++++++++++++--
    include/linux/tty.h | 8 +++++++-
    2 files changed, 34 insertions(+), 3 deletions(-)

    --- a/drivers/char/tty_port.c
    +++ b/drivers/char/tty_port.c
    @@ -96,6 +96,14 @@ void tty_port_tty_set(struct tty_port *p
    }
    EXPORT_SYMBOL(tty_port_tty_set);

    +static void tty_port_shutdown(struct tty_port *port)
    +{
    + if (port->ops->shutdown &&
    + test_and_clear_bit(ASYNC_INITIALIZED, &port->flags))
    + port->ops->shutdown(port);
    +
    +}
    +
    /**
    * tty_port_hangup - hangup helper
    * @port: tty port
    @@ -116,6 +124,7 @@ void tty_port_hangup(struct tty_port *po
    port->tty = NULL;
    spin_unlock_irqrestore(&port->lock, flags);
    wake_up_interruptible(&port->open_wait);
    + tty_port_shutdown(port);
    }
    EXPORT_SYMBOL(tty_port_hangup);

    @@ -296,15 +305,17 @@ int tty_port_close_start(struct tty_port

    if (port->count) {
    spin_unlock_irqrestore(&port->lock, flags);
    + if (port->ops->drop)
    + port->ops->drop(port);
    return 0;
    }
    - port->flags |= ASYNC_CLOSING;
    + set_bit(ASYNC_CLOSING, &port->flags);
    tty->closing = 1;
    spin_unlock_irqrestore(&port->lock, flags);
    /* Don't block on a stalled port, just pull the chain */
    if (tty->flow_stopped)
    tty_driver_flush_buffer(tty);
    - if (port->flags & ASYNC_INITIALIZED &&
    + if (test_bit(ASYNCB_INITIALIZED, &port->flags) &&
    port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
    tty_wait_until_sent(tty, port->closing_wait);
    if (port->drain_delay) {
    @@ -318,6 +329,9 @@ int tty_port_close_start(struct tty_port
    timeout = 2 * HZ;
    schedule_timeout_interruptible(timeout);
    }
    + /* Don't call port->drop for the last reference. Callers will want
    + to drop the last active reference in ->shutdown() or the tty
    + shutdown path */
    return 1;
    }
    EXPORT_SYMBOL(tty_port_close_start);
    @@ -348,3 +362,14 @@ void tty_port_close_end(struct tty_port
    spin_unlock_irqrestore(&port->lock, flags);
    }
    EXPORT_SYMBOL(tty_port_close_end);
    +
    +void tty_port_close(struct tty_port *port, struct tty_struct *tty,
    + struct file *filp)
    +{
    + if (tty_port_close_start(port, tty, filp) == 0)
    + return;
    + tty_port_shutdown(port);
    + tty_port_close_end(port, tty);
    + tty_port_tty_set(port, NULL);
    +}
    +EXPORT_SYMBOL(tty_port_close);
    --- a/include/linux/tty.h
    +++ b/include/linux/tty.h
    @@ -185,7 +185,12 @@ struct tty_port;
    struct tty_port_operations {
    /* Return 1 if the carrier is raised */
    int (*carrier_raised)(struct tty_port *port);
    + /* Control the DTR line */
    void (*dtr_rts)(struct tty_port *port, int raise);
    + /* Called when the last close completes or a hangup finishes
    + IFF the port was initialized. Do not use to free resources */
    + void (*shutdown)(struct tty_port *port);
    + void (*drop)(struct tty_port *port);
    };

    struct tty_port {
    @@ -457,7 +462,8 @@ extern int tty_port_block_til_ready(stru
    extern int tty_port_close_start(struct tty_port *port,
    struct tty_struct *tty, struct file *filp);
    extern void tty_port_close_end(struct tty_port *port, struct tty_struct *tty);
    -
    +extern void tty_port_close(struct tty_port *port,
    + struct tty_struct *tty, struct file *filp);
    extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc);
    extern int tty_unregister_ldisc(int disc);
    extern int tty_set_ldisc(struct tty_struct *tty, int ldisc);



    \
     
     \ /
      Last update: 2009-10-02 04:15    [W:0.025 / U:0.652 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site