lkml.org 
[lkml]   [2009]   [Sep]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 39/79] tty: USB can now use the shutdown method for kref based freeing of ports
Date
From: Alan Cox <alan@linux.intel.com>

Signed-off-by: Alan Cox <alan@linux.intel.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/usb/serial/usb-serial.c | 28 +++++++---------------------
1 files changed, 7 insertions(+), 21 deletions(-)

diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 21dd72a..31c7a09 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -316,16 +316,19 @@ static void serial_do_down(struct usb_serial_port *port)
*
* Do the resource freeing and refcount dropping for the port. We must
* be careful about ordering and we must avoid freeing up the console.
+ *
+ * Called when the last tty kref is dropped.
*/

-static void serial_do_free(struct usb_serial_port *port)
+static void serial_do_free(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial;
struct module *owner;

/* The console is magical, do not hang up the console hardware
or there will be tears */
- if (port->console)
+ if (port == NULL || port->console)
return;

serial = port->serial;
@@ -350,30 +353,12 @@ static void serial_close(struct tty_struct *tty, struct file *filp)

dbg("%s - port %d", __func__, port->number);

- /* FIXME:
- This leaves a very narrow race. Really we should do the
- serial_do_free() on tty->shutdown(), but tty->shutdown can
- be called from IRQ context and serial_do_free can sleep.
-
- The right fix is probably to make the tty free (which is rare)
- and thus tty->shutdown() occur via a work queue and simplify all
- the drivers that use it.
- */
- if (tty_hung_up_p(filp)) {
- /* serial_hangup already called serial_down at this point.
- Another user may have already reopened the port but
- serial_do_free is refcounted */
- serial_do_free(port);
- return;
- }
-
if (tty_port_close_start(&port->port, tty, filp) == 0)
return;
-
serial_do_down(port);
tty_port_close_end(&port->port, tty);
tty_port_tty_set(&port->port, NULL);
- serial_do_free(port);
+
}

static void serial_hangup(struct tty_struct *tty)
@@ -1243,6 +1228,7 @@ static const struct tty_operations serial_ops = {
.chars_in_buffer = serial_chars_in_buffer,
.tiocmget = serial_tiocmget,
.tiocmset = serial_tiocmset,
+ .shutdown = serial_do_free,
.proc_fops = &serial_proc_fops,
};

--
1.6.4.2


\
 
 \ /
  Last update: 2009-09-20 00:15    [W:0.633 / U:0.648 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site