Commit 9f8c0b08 authored by Jiri Slaby's avatar Jiri Slaby Committed by Greg Kroah-Hartman

TTY: hso, use tty from tty_port

We switched tty refcounting there to the one provided by tty_port
helpers. So tty_port->tty is now protected by tty_port->lock, not by
hso_serial->serial_lock.

Side note: tty->driver_data does not need the lock, so it is needed
neither in open, nor in close paths.
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
Cc: Jan Dumon <j.dumon@option.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 30409420
...@@ -250,7 +250,6 @@ struct hso_serial { ...@@ -250,7 +250,6 @@ struct hso_serial {
struct tty_port port; struct tty_port port;
/* from usb_serial_port */ /* from usb_serial_port */
struct tty_struct *tty;
spinlock_t serial_lock; spinlock_t serial_lock;
int (*write_data) (struct hso_serial *serial); int (*write_data) (struct hso_serial *serial);
...@@ -1297,11 +1296,8 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) ...@@ -1297,11 +1296,8 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
kref_get(&serial->parent->ref); kref_get(&serial->parent->ref);
/* setup */ /* setup */
spin_lock_irq(&serial->serial_lock);
tty->driver_data = serial; tty->driver_data = serial;
tty_kref_put(serial->tty); tty_port_tty_set(&serial->port, tty);
serial->tty = tty_kref_get(tty);
spin_unlock_irq(&serial->serial_lock);
/* check for port already opened, if not set the termios */ /* check for port already opened, if not set the termios */
serial->port.count++; serial->port.count++;
...@@ -1358,13 +1354,7 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) ...@@ -1358,13 +1354,7 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
if (serial->port.count <= 0) { if (serial->port.count <= 0) {
serial->port.count = 0; serial->port.count = 0;
spin_lock_irq(&serial->serial_lock); tty_port_tty_set(&serial->port, NULL);
if (serial->tty == tty) {
serial->tty->driver_data = NULL;
serial->tty = NULL;
tty_kref_put(tty);
}
spin_unlock_irq(&serial->serial_lock);
if (!usb_gone) if (!usb_gone)
hso_stop_serial_device(serial->parent); hso_stop_serial_device(serial->parent);
tasklet_kill(&serial->unthrottle_tasklet); tasklet_kill(&serial->unthrottle_tasklet);
...@@ -1947,14 +1937,13 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) ...@@ -1947,14 +1937,13 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb)
spin_lock(&serial->serial_lock); spin_lock(&serial->serial_lock);
serial->tx_urb_used = 0; serial->tx_urb_used = 0;
tty = tty_kref_get(serial->tty);
spin_unlock(&serial->serial_lock); spin_unlock(&serial->serial_lock);
if (status) { if (status) {
handle_usb_error(status, __func__, serial->parent); handle_usb_error(status, __func__, serial->parent);
tty_kref_put(tty);
return; return;
} }
hso_put_activity(serial->parent); hso_put_activity(serial->parent);
tty = tty_port_tty_get(&serial->port);
if (tty) { if (tty) {
tty_wakeup(tty); tty_wakeup(tty);
tty_kref_put(tty); tty_kref_put(tty);
...@@ -1994,7 +1983,6 @@ static void ctrl_callback(struct urb *urb) ...@@ -1994,7 +1983,6 @@ static void ctrl_callback(struct urb *urb)
struct hso_serial *serial = urb->context; struct hso_serial *serial = urb->context;
struct usb_ctrlrequest *req; struct usb_ctrlrequest *req;
int status = urb->status; int status = urb->status;
struct tty_struct *tty;
/* sanity check */ /* sanity check */
if (!serial) if (!serial)
...@@ -2002,11 +1990,9 @@ static void ctrl_callback(struct urb *urb) ...@@ -2002,11 +1990,9 @@ static void ctrl_callback(struct urb *urb)
spin_lock(&serial->serial_lock); spin_lock(&serial->serial_lock);
serial->tx_urb_used = 0; serial->tx_urb_used = 0;
tty = tty_kref_get(serial->tty);
spin_unlock(&serial->serial_lock); spin_unlock(&serial->serial_lock);
if (status) { if (status) {
handle_usb_error(status, __func__, serial->parent); handle_usb_error(status, __func__, serial->parent);
tty_kref_put(tty);
return; return;
} }
...@@ -2024,13 +2010,15 @@ static void ctrl_callback(struct urb *urb) ...@@ -2024,13 +2010,15 @@ static void ctrl_callback(struct urb *urb)
put_rxbuf_data_and_resubmit_ctrl_urb(serial); put_rxbuf_data_and_resubmit_ctrl_urb(serial);
spin_unlock(&serial->serial_lock); spin_unlock(&serial->serial_lock);
} else { } else {
struct tty_struct *tty = tty_port_tty_get(&serial->port);
hso_put_activity(serial->parent); hso_put_activity(serial->parent);
if (tty) if (tty) {
tty_wakeup(tty); tty_wakeup(tty);
tty_kref_put(tty);
}
/* response to a write command */ /* response to a write command */
hso_kick_transmit(serial); hso_kick_transmit(serial);
} }
tty_kref_put(tty);
} }
/* handle RX data for serial port */ /* handle RX data for serial port */
...@@ -2046,8 +2034,7 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) ...@@ -2046,8 +2034,7 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
return -2; return -2;
} }
/* All callers to put_rxbuf_data hold serial_lock */ tty = tty_port_tty_get(&serial->port);
tty = tty_kref_get(serial->tty);
/* Push data to tty */ /* Push data to tty */
if (tty) { if (tty) {
...@@ -2067,12 +2054,12 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) ...@@ -2067,12 +2054,12 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
write_length_remaining -= curr_write_len; write_length_remaining -= curr_write_len;
tty_flip_buffer_push(tty); tty_flip_buffer_push(tty);
} }
tty_kref_put(tty);
} }
if (write_length_remaining == 0) { if (write_length_remaining == 0) {
serial->curr_rx_urb_offset = 0; serial->curr_rx_urb_offset = 0;
serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0;
} }
tty_kref_put(tty);
return write_length_remaining; return write_length_remaining;
} }
...@@ -3166,13 +3153,12 @@ static void hso_free_interface(struct usb_interface *interface) ...@@ -3166,13 +3153,12 @@ static void hso_free_interface(struct usb_interface *interface)
if (serial_table[i] && if (serial_table[i] &&
(serial_table[i]->interface == interface)) { (serial_table[i]->interface == interface)) {
hso_dev = dev2ser(serial_table[i]); hso_dev = dev2ser(serial_table[i]);
spin_lock_irq(&hso_dev->serial_lock); tty = tty_port_tty_get(&hso_dev->port);
tty = tty_kref_get(hso_dev->tty); if (tty) {
spin_unlock_irq(&hso_dev->serial_lock);
if (tty)
tty_hangup(tty); tty_hangup(tty);
mutex_lock(&hso_dev->parent->mutex);
tty_kref_put(tty); tty_kref_put(tty);
}
mutex_lock(&hso_dev->parent->mutex);
hso_dev->parent->usb_gone = 1; hso_dev->parent->usb_gone = 1;
mutex_unlock(&hso_dev->parent->mutex); mutex_unlock(&hso_dev->parent->mutex);
kref_put(&serial_table[i]->ref, hso_serial_ref_free); kref_put(&serial_table[i]->ref, hso_serial_ref_free);
......
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