summaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/ftdi_sio.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-10-13 10:39:46 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 09:51:41 -0700
commit4a90f09b20f4622dcbff1f0e1e6bae1704f8ad8c (patch)
tree9b275f88f2705cb10121d5982741aef3a088a7c8 /drivers/usb/serial/ftdi_sio.c
parent95f9bfc6b76e862265a2d70ae061eec18fe14140 (diff)
tty: usb-serial krefs
Use kref in the USB serial drivers so that we don't free tty structures from under the URB receive handlers as has historically been the case if you were unlucky. This also gives us a framework for general tty drivers to use tty_port objects and refcount. Contains two err->dev_err changes merged together to fix clashes in the -next tree. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r--drivers/usb/serial/ftdi_sio.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 1ac7e802b4b..c2ac129557a 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -1808,7 +1808,7 @@ static void ftdi_read_bulk_callback(struct urb *urb)
if (port->port.count <= 0)
return;
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (!tty) {
dbg("%s - bad tty pointer - exiting", __func__);
return;
@@ -1817,7 +1817,7 @@ static void ftdi_read_bulk_callback(struct urb *urb)
priv = usb_get_serial_port_data(port);
if (!priv) {
dbg("%s - bad port private data pointer - exiting", __func__);
- return;
+ goto out;
}
if (urb != port->read_urb)
@@ -1827,7 +1827,7 @@ static void ftdi_read_bulk_callback(struct urb *urb)
/* This will happen at close every time so it is a dbg not an
err */
dbg("(this is ok on close) nonzero read bulk status received: %d", status);
- return;
+ goto out;
}
/* count data bytes, but not status bytes */
@@ -1838,7 +1838,8 @@ static void ftdi_read_bulk_callback(struct urb *urb)
spin_unlock_irqrestore(&priv->rx_lock, flags);
ftdi_process_read(&priv->rx_work.work);
-
+out:
+ tty_kref_put(tty);
} /* ftdi_read_bulk_callback */
@@ -1863,7 +1864,7 @@ static void ftdi_process_read(struct work_struct *work)
if (port->port.count <= 0)
return;
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (!tty) {
dbg("%s - bad tty pointer - exiting", __func__);
return;
@@ -1872,13 +1873,13 @@ static void ftdi_process_read(struct work_struct *work)
priv = usb_get_serial_port_data(port);
if (!priv) {
dbg("%s - bad port private data pointer - exiting", __func__);
- return;
+ goto out;
}
urb = port->read_urb;
if (!urb) {
dbg("%s - bad read_urb pointer - exiting", __func__);
- return;
+ goto out;
}
data = urb->transfer_buffer;
@@ -2020,7 +2021,7 @@ static void ftdi_process_read(struct work_struct *work)
schedule_delayed_work(&priv->rx_work, 1);
else
dbg("%s - port is closed", __func__);
- return;
+ goto out;
}
/* urb is completely processed */
@@ -2041,6 +2042,8 @@ static void ftdi_process_read(struct work_struct *work)
err("%s - failed resubmitting read urb, error %d",
__func__, result);
}
+out:
+ tty_kref_put(tty);
} /* ftdi_process_read */