Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+13 −27
Original line number Diff line number Diff line
@@ -250,7 +250,6 @@ struct hso_serial {

	struct tty_port port;
	/* from usb_serial_port */
	struct tty_struct *tty;
	spinlock_t serial_lock;

	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);

	/* setup */
	spin_lock_irq(&serial->serial_lock);
	tty->driver_data = serial;
	tty_kref_put(serial->tty);
	serial->tty = tty_kref_get(tty);
	spin_unlock_irq(&serial->serial_lock);
	tty_port_tty_set(&serial->port, tty);

	/* check for port already opened, if not set the termios */
	serial->port.count++;
@@ -1358,13 +1354,7 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)

	if (serial->port.count <= 0) {
		serial->port.count = 0;
		spin_lock_irq(&serial->serial_lock);
		if (serial->tty == tty) {
			serial->tty->driver_data = NULL;
			serial->tty = NULL;
			tty_kref_put(tty);
		}
		spin_unlock_irq(&serial->serial_lock);
		tty_port_tty_set(&serial->port, NULL);
		if (!usb_gone)
			hso_stop_serial_device(serial->parent);
		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);
	serial->tx_urb_used = 0;
	tty = tty_kref_get(serial->tty);
	spin_unlock(&serial->serial_lock);
	if (status) {
		handle_usb_error(status, __func__, serial->parent);
		tty_kref_put(tty);
		return;
	}
	hso_put_activity(serial->parent);
	tty = tty_port_tty_get(&serial->port);
	if (tty) {
		tty_wakeup(tty);
		tty_kref_put(tty);
@@ -1994,7 +1983,6 @@ static void ctrl_callback(struct urb *urb)
	struct hso_serial *serial = urb->context;
	struct usb_ctrlrequest *req;
	int status = urb->status;
	struct tty_struct *tty;

	/* sanity check */
	if (!serial)
@@ -2002,11 +1990,9 @@ static void ctrl_callback(struct urb *urb)

	spin_lock(&serial->serial_lock);
	serial->tx_urb_used = 0;
	tty = tty_kref_get(serial->tty);
	spin_unlock(&serial->serial_lock);
	if (status) {
		handle_usb_error(status, __func__, serial->parent);
		tty_kref_put(tty);
		return;
	}

@@ -2024,13 +2010,15 @@ static void ctrl_callback(struct urb *urb)
		put_rxbuf_data_and_resubmit_ctrl_urb(serial);
		spin_unlock(&serial->serial_lock);
	} else {
		struct tty_struct *tty = tty_port_tty_get(&serial->port);
		hso_put_activity(serial->parent);
		if (tty)
		if (tty) {
			tty_wakeup(tty);
			tty_kref_put(tty);
		}
		/* response to a write command */
		hso_kick_transmit(serial);
	}
	tty_kref_put(tty);
}

/* handle RX data for serial port */
@@ -2046,8 +2034,7 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
		return -2;
	}

	/* All callers to put_rxbuf_data hold serial_lock */
	tty = tty_kref_get(serial->tty);
	tty = tty_port_tty_get(&serial->port);

	/* Push data to 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;
			tty_flip_buffer_push(tty);
		}
		tty_kref_put(tty);
	}
	if (write_length_remaining == 0) {
		serial->curr_rx_urb_offset = 0;
		serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0;
	}
	tty_kref_put(tty);
	return write_length_remaining;
}

@@ -3166,13 +3153,12 @@ static void hso_free_interface(struct usb_interface *interface)
		if (serial_table[i] &&
		    (serial_table[i]->interface == interface)) {
			hso_dev = dev2ser(serial_table[i]);
			spin_lock_irq(&hso_dev->serial_lock);
			tty = tty_kref_get(hso_dev->tty);
			spin_unlock_irq(&hso_dev->serial_lock);
			if (tty)
			tty = tty_port_tty_get(&hso_dev->port);
			if (tty) {
				tty_hangup(tty);
			mutex_lock(&hso_dev->parent->mutex);
				tty_kref_put(tty);
			}
			mutex_lock(&hso_dev->parent->mutex);
			hso_dev->parent->usb_gone = 1;
			mutex_unlock(&hso_dev->parent->mutex);
			kref_put(&serial_table[i]->ref, hso_serial_ref_free);