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: Jiri Slaby <jslaby@suse.cz> Cc: Jan Dumon <j.dumon@option.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
30409420d2
commit
9f8c0b081d
|
@ -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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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);
|
||||||
|
tty_kref_put(tty);
|
||||||
|
}
|
||||||
mutex_lock(&hso_dev->parent->mutex);
|
mutex_lock(&hso_dev->parent->mutex);
|
||||||
tty_kref_put(tty);
|
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue