diff options
author | Alan Cox <alan@redhat.com> | 2008-10-13 05:39:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-13 12:51:41 -0400 |
commit | 4a90f09b20f4622dcbff1f0e1e6bae1704f8ad8c (patch) | |
tree | 9b275f88f2705cb10121d5982741aef3a088a7c8 /drivers/usb/serial/safe_serial.c | |
parent | 95f9bfc6b76e862265a2d70ae061eec18fe14140 (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/safe_serial.c')
-rw-r--r-- | drivers/usb/serial/safe_serial.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index def52d07a4ea..72903ac9f5c0 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c | |||
@@ -217,6 +217,7 @@ static void safe_read_bulk_callback(struct urb *urb) | |||
217 | struct usb_serial_port *port = urb->context; | 217 | struct usb_serial_port *port = urb->context; |
218 | unsigned char *data = urb->transfer_buffer; | 218 | unsigned char *data = urb->transfer_buffer; |
219 | unsigned char length = urb->actual_length; | 219 | unsigned char length = urb->actual_length; |
220 | struct tty_struct *tty; | ||
220 | int result; | 221 | int result; |
221 | int status = urb->status; | 222 | int status = urb->status; |
222 | 223 | ||
@@ -242,6 +243,7 @@ static void safe_read_bulk_callback(struct urb *urb) | |||
242 | printk("\n"); | 243 | printk("\n"); |
243 | } | 244 | } |
244 | #endif | 245 | #endif |
246 | tty = tty_port_tty_get(&port->port); | ||
245 | if (safe) { | 247 | if (safe) { |
246 | __u16 fcs; | 248 | __u16 fcs; |
247 | fcs = fcs_compute10(data, length, CRC10_INITFCS); | 249 | fcs = fcs_compute10(data, length, CRC10_INITFCS); |
@@ -250,9 +252,9 @@ static void safe_read_bulk_callback(struct urb *urb) | |||
250 | if (actual_length <= (length - 2)) { | 252 | if (actual_length <= (length - 2)) { |
251 | info("%s - actual: %d", __func__, | 253 | info("%s - actual: %d", __func__, |
252 | actual_length); | 254 | actual_length); |
253 | tty_insert_flip_string(port->port.tty, | 255 | tty_insert_flip_string(tty, |
254 | data, actual_length); | 256 | data, actual_length); |
255 | tty_flip_buffer_push(port->port.tty); | 257 | tty_flip_buffer_push(tty); |
256 | } else { | 258 | } else { |
257 | err("%s - inconsistent lengths %d:%d", | 259 | err("%s - inconsistent lengths %d:%d", |
258 | __func__, actual_length, length); | 260 | __func__, actual_length, length); |
@@ -261,9 +263,10 @@ static void safe_read_bulk_callback(struct urb *urb) | |||
261 | err("%s - bad CRC %x", __func__, fcs); | 263 | err("%s - bad CRC %x", __func__, fcs); |
262 | } | 264 | } |
263 | } else { | 265 | } else { |
264 | tty_insert_flip_string(port->port.tty, data, length); | 266 | tty_insert_flip_string(tty, data, length); |
265 | tty_flip_buffer_push(port->port.tty); | 267 | tty_flip_buffer_push(tty); |
266 | } | 268 | } |
269 | tty_kref_put(tty); | ||
267 | 270 | ||
268 | /* Continue trying to always read */ | 271 | /* Continue trying to always read */ |
269 | usb_fill_bulk_urb(urb, port->serial->dev, | 272 | usb_fill_bulk_urb(urb, port->serial->dev, |