Commit 95cc0418 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

[PATCH] USB: fix bug for multiple opens on ttyUSB devices.

This patch fixes the bug where running ppp over a ttyUSB device would fail.
parent 08bceb43
...@@ -493,12 +493,15 @@ static int serial_open (struct tty_struct *tty, struct file * filp) ...@@ -493,12 +493,15 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
return retval; return retval;
} }
static void __serial_close(struct usb_serial_port *port, struct file *filp) static void serial_close(struct tty_struct *tty, struct file * filp)
{ {
if (!port->open_count) { struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
dbg ("%s - port not opened", __FUNCTION__); struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
if (!serial)
return; return;
}
dbg("%s - port %d", __FUNCTION__, port->number);
--port->open_count; --port->open_count;
if (port->open_count <= 0) { if (port->open_count <= 0) {
...@@ -506,30 +509,18 @@ static void __serial_close(struct usb_serial_port *port, struct file *filp) ...@@ -506,30 +509,18 @@ static void __serial_close(struct usb_serial_port *port, struct file *filp)
* port is being closed by the last owner */ * port is being closed by the last owner */
port->serial->type->close(port, filp); port->serial->type->close(port, filp);
port->open_count = 0; port->open_count = 0;
if (port->tty) {
if (port->tty->driver_data)
port->tty->driver_data = NULL;
port->tty = NULL;
}
} }
module_put(port->serial->type->owner); module_put(port->serial->type->owner);
kobject_put(&port->serial->kobj); kobject_put(&port->serial->kobj);
} }
static void serial_close(struct tty_struct *tty, struct file * filp)
{
struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
if (!serial)
return;
dbg("%s - port %d", __FUNCTION__, port->number);
/* if disconnect beat us to the punch here, there's nothing to do */
if (tty && tty->driver_data) {
__serial_close(port, filp);
tty->driver_data = NULL;
}
port->tty = NULL;
}
static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count) static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count)
{ {
struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
...@@ -848,19 +839,6 @@ static void destroy_serial (struct kobject *kobj) ...@@ -848,19 +839,6 @@ static void destroy_serial (struct kobject *kobj)
dbg ("%s - %s", __FUNCTION__, kobj->name); dbg ("%s - %s", __FUNCTION__, kobj->name);
serial = to_usb_serial(kobj); serial = to_usb_serial(kobj);
/* fail all future close/read/write/ioctl/etc calls */
for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i];
if (port->tty != NULL) {
port->tty->driver_data = NULL;
while (port->open_count > 0) {
__serial_close(port, NULL);
}
port->tty = NULL;
}
}
serial_shutdown (serial); serial_shutdown (serial);
/* return the minor range that this device had */ /* return the minor range that this device had */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment