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

Commit 5ce76e77 authored by Jiri Slaby's avatar Jiri Slaby Committed by Greg Kroah-Hartman
Browse files

TTY: hso, add tty_port



And use open count from there. Other members will follow.

Remark: port.count is (and never was) properly protected. Only a mutex
is held, so ISR and all the functions it calls may see an invalid
state.

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 d230788f
Loading
Loading
Loading
Loading
+13 −12
Original line number Diff line number Diff line
@@ -255,9 +255,9 @@ struct hso_serial {
	u8 dtr_state;
	unsigned tx_urb_used:1;

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

	int (*write_data) (struct hso_serial *serial);
@@ -1190,7 +1190,7 @@ static void put_rxbuf_data_and_resubmit_ctrl_urb(struct hso_serial *serial)
	struct urb *urb;

	urb = serial->rx_urb[0];
	if (serial->open_count > 0) {
	if (serial->port.count > 0) {
		count = put_rxbuf_data(urb, serial);
		if (count == -1)
			return;
@@ -1226,7 +1226,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb)
	DUMP1(urb->transfer_buffer, urb->actual_length);

	/* Anyone listening? */
	if (serial->open_count == 0)
	if (serial->port.count == 0)
		return;

	if (status == 0) {
@@ -1311,8 +1311,8 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
	spin_unlock_irq(&serial->serial_lock);

	/* check for port already opened, if not set the termios */
	serial->open_count++;
	if (serial->open_count == 1) {
	serial->port.count++;
	if (serial->port.count == 1) {
		serial->rx_state = RX_IDLE;
		/* Force default termio settings */
		_hso_serial_set_termios(tty, NULL);
@@ -1324,7 +1324,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
		result = hso_start_serial_device(serial->parent, GFP_KERNEL);
		if (result) {
			hso_stop_serial_device(serial->parent);
			serial->open_count--;
			serial->port.count--;
			kref_put(&serial->parent->ref, hso_serial_ref_free);
		}
	} else {
@@ -1361,10 +1361,10 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)

	/* reset the rts and dtr */
	/* do the actual close */
	serial->open_count--;
	serial->port.count--;

	if (serial->open_count <= 0) {
		serial->open_count = 0;
	if (serial->port.count <= 0) {
		serial->port.count = 0;
		spin_lock_irq(&serial->serial_lock);
		if (serial->tty == tty) {
			serial->tty->driver_data = NULL;
@@ -1446,7 +1446,7 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old)

	/* the actual setup */
	spin_lock_irqsave(&serial->serial_lock, flags);
	if (serial->open_count)
	if (serial->port.count)
		_hso_serial_set_termios(tty, old);
	else
		tty->termios = old;
@@ -1905,7 +1905,7 @@ static void intr_callback(struct urb *urb)
				D1("Pending read interrupt on port %d\n", i);
				spin_lock(&serial->serial_lock);
				if (serial->rx_state == RX_IDLE &&
					serial->open_count > 0) {
					serial->port.count > 0) {
					/* Setup and send a ctrl req read on
					 * port i */
					if (!serial->rx_urb_filled[0]) {
@@ -2320,6 +2320,7 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
	serial->minor = minor;
	serial->magic = HSO_SERIAL_MAGIC;
	spin_lock_init(&serial->serial_lock);
	tty_port_init(&serial->port);
	serial->num_rx_urbs = num_urbs;

	/* RX, allocate urb and initialize */
@@ -3098,7 +3099,7 @@ static int hso_resume(struct usb_interface *iface)
	/* Start all serial ports */
	for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
		if (serial_table[i] && (serial_table[i]->interface == iface)) {
			if (dev2ser(serial_table[i])->open_count) {
			if (dev2ser(serial_table[i])->port.count) {
				result =
				    hso_start_serial_device(serial_table[i], GFP_NOIO);
				hso_kick_transmit(dev2ser(serial_table[i]));