linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jiri Slaby <jslaby@suse.cz>
To: gregkh@linuxfoundation.org
Cc: alan@linux.intel.com, linux-kernel@vger.kernel.org,
	jirislaby@gmail.com, linuxppc-dev@lists.ozlabs.org
Subject: [PATCH 45/69] TTY: hvsi, sanitize uses of tty
Date: Mon,  2 Apr 2012 13:54:29 +0200	[thread overview]
Message-ID: <1333367693-3244-46-git-send-email-jslaby@suse.cz> (raw)
In-Reply-To: <1333367693-3244-1-git-send-email-jslaby@suse.cz>

- use tty, not hp->tty wherever possible
- pass tty down to some functions and go to step one
- do not defer tty_hangup calls -- it is as simple as schedule_work,
  so might be called with hp->lock held
- do not defer tty buffer flips -- since the driver does not use
  low_latency (it cannot actually), the flip is a simple tail move
  plus schedule_work. It will make our life easier in the next patch.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: linuxppc-dev@lists.ozlabs.org
---
 drivers/tty/hvc/hvsi.c |   88 +++++++++++++++++-------------------------------
 1 file changed, 30 insertions(+), 58 deletions(-)

diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c
index 113a09a..68b729b 100644
--- a/drivers/tty/hvc/hvsi.c
+++ b/drivers/tty/hvc/hvsi.c
@@ -237,7 +237,7 @@ static int hvsi_read(struct hvsi_struct *hp, char *buf, int count)
 }
 
 static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,
-	struct tty_struct **to_hangup, struct hvsi_struct **to_handshake)
+	struct tty_struct *tty, struct hvsi_struct **to_handshake)
 {
 	struct hvsi_control *header = (struct hvsi_control *)packet;
 
@@ -247,9 +247,8 @@ static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,
 				/* CD went away; no more connection */
 				pr_debug("hvsi%i: CD dropped\n", hp->index);
 				hp->mctrl &= TIOCM_CD;
-				/* If userland hasn't done an open(2) yet, hp->tty is NULL. */
-				if (hp->tty && !C_CLOCAL(hp->tty))
-					*to_hangup = hp->tty;
+				if (tty && !C_CLOCAL(tty))
+					tty_hangup(tty);
 			}
 			break;
 		case VSV_CLOSE_PROTOCOL:
@@ -331,7 +330,8 @@ static void hvsi_recv_query(struct hvsi_struct *hp, uint8_t *packet)
 	}
 }
 
-static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len)
+static void hvsi_insert_chars(struct hvsi_struct *hp, struct tty_struct *tty,
+		const char *buf, int len)
 {
 	int i;
 
@@ -347,7 +347,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len)
 			continue;
 		}
 #endif /* CONFIG_MAGIC_SYSRQ */
-		tty_insert_flip_char(hp->tty, c, 0);
+		tty_insert_flip_char(tty, c, 0);
 	}
 }
 
@@ -360,7 +360,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len)
  * revisited.
  */
 #define TTY_THRESHOLD_THROTTLE 128
-static struct tty_struct *hvsi_recv_data(struct hvsi_struct *hp,
+static bool hvsi_recv_data(struct hvsi_struct *hp, struct tty_struct *tty,
 		const uint8_t *packet)
 {
 	const struct hvsi_header *header = (const struct hvsi_header *)packet;
@@ -371,14 +371,14 @@ static struct tty_struct *hvsi_recv_data(struct hvsi_struct *hp,
 	pr_debug("queueing %i chars '%.*s'\n", datalen, datalen, data);
 
 	if (datalen == 0)
-		return NULL;
+		return false;
 
 	if (overflow > 0) {
 		pr_debug("%s: got >TTY_THRESHOLD_THROTTLE bytes\n", __func__);
 		datalen = TTY_THRESHOLD_THROTTLE;
 	}
 
-	hvsi_insert_chars(hp, data, datalen);
+	hvsi_insert_chars(hp, tty, data, datalen);
 
 	if (overflow > 0) {
 		/*
@@ -390,7 +390,7 @@ static struct tty_struct *hvsi_recv_data(struct hvsi_struct *hp,
 		hp->n_throttle = overflow;
 	}
 
-	return hp->tty;
+	return true;
 }
 
 /*
@@ -399,14 +399,13 @@ static struct tty_struct *hvsi_recv_data(struct hvsi_struct *hp,
  * machine during console handshaking (in which case tty = NULL and we ignore
  * incoming data).
  */
-static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip,
-		struct tty_struct **hangup, struct hvsi_struct **handshake)
+static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct *tty,
+		struct hvsi_struct **handshake)
 {
 	uint8_t *packet = hp->inbuf;
 	int chunklen;
+	bool flip = false;
 
-	*flip = NULL;
-	*hangup = NULL;
 	*handshake = NULL;
 
 	chunklen = hvsi_read(hp, hp->inbuf_end, HVSI_MAX_READ);
@@ -440,12 +439,12 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip,
 			case VS_DATA_PACKET_HEADER:
 				if (!is_open(hp))
 					break;
-				if (hp->tty == NULL)
+				if (tty == NULL)
 					break; /* no tty buffer to put data in */
-				*flip = hvsi_recv_data(hp, packet);
+				flip = hvsi_recv_data(hp, tty, packet);
 				break;
 			case VS_CONTROL_PACKET_HEADER:
-				hvsi_recv_control(hp, packet, hangup, handshake);
+				hvsi_recv_control(hp, packet, tty, handshake);
 				break;
 			case VS_QUERY_RESPONSE_PACKET_HEADER:
 				hvsi_recv_response(hp, packet);
@@ -462,28 +461,26 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip,
 
 		packet += len_packet(packet);
 
-		if (*hangup || *handshake) {
-			pr_debug("%s: hangup or handshake\n", __func__);
-			/*
-			 * we need to send the hangup now before receiving any more data.
-			 * If we get "data, hangup, data", we can't deliver the second
-			 * data before the hangup.
-			 */
+		if (*handshake) {
+			pr_debug("%s: handshake\n", __func__);
 			break;
 		}
 	}
 
 	compact_inbuf(hp, packet);
 
+	if (flip)
+		tty_flip_buffer_push(tty);
+
 	return 1;
 }
 
-static void hvsi_send_overflow(struct hvsi_struct *hp)
+static void hvsi_send_overflow(struct hvsi_struct *hp, struct tty_struct *tty)
 {
 	pr_debug("%s: delivering %i bytes overflow\n", __func__,
 			hp->n_throttle);
 
-	hvsi_insert_chars(hp, hp->throttle_buf, hp->n_throttle);
+	hvsi_insert_chars(hp, tty, hp->throttle_buf, hp->n_throttle);
 	hp->n_throttle = 0;
 }
 
@@ -494,8 +491,6 @@ static void hvsi_send_overflow(struct hvsi_struct *hp)
 static irqreturn_t hvsi_interrupt(int irq, void *arg)
 {
 	struct hvsi_struct *hp = (struct hvsi_struct *)arg;
-	struct tty_struct *flip;
-	struct tty_struct *hangup;
 	struct hvsi_struct *handshake;
 	unsigned long flags;
 	int again = 1;
@@ -504,25 +499,9 @@ static irqreturn_t hvsi_interrupt(int irq, void *arg)
 
 	while (again) {
 		spin_lock_irqsave(&hp->lock, flags);
-		again = hvsi_load_chunk(hp, &flip, &hangup, &handshake);
+		again = hvsi_load_chunk(hp, hp->tty, &handshake);
 		spin_unlock_irqrestore(&hp->lock, flags);
 
-		/*
-		 * we have to call tty_flip_buffer_push() and tty_hangup() outside our
-		 * spinlock. But we also have to keep going until we've read all the
-		 * available data.
-		 */
-
-		if (flip) {
-			/* there was data put in the tty flip buffer */
-			tty_flip_buffer_push(flip);
-			flip = NULL;
-		}
-
-		if (hangup) {
-			tty_hangup(hangup);
-		}
-
 		if (handshake) {
 			pr_debug("hvsi%i: attempting re-handshake\n", handshake->index);
 			schedule_work(&handshake->handshaker);
@@ -534,15 +513,11 @@ static irqreturn_t hvsi_interrupt(int irq, void *arg)
 			&& (!test_bit(TTY_THROTTLED, &hp->tty->flags))) {
 		/* we weren't hung up and we weren't throttled, so we can deliver the
 		 * rest now */
-		flip = hp->tty;
-		hvsi_send_overflow(hp);
+		hvsi_send_overflow(hp, hp->tty);
+		tty_flip_buffer_push(hp->tty);
 	}
 	spin_unlock_irqrestore(&hp->lock, flags);
 
-	if (flip) {
-		tty_flip_buffer_push(flip);
-	}
-
 	return IRQ_HANDLED;
 }
 
@@ -966,8 +941,8 @@ static int hvsi_write(struct tty_struct *tty,
 	 * and hvsi_write_worker will be scheduled. subsequent hvsi_write() calls
 	 * will see there is no room in outbuf and return.
 	 */
-	while ((count > 0) && (hvsi_write_room(hp->tty) > 0)) {
-		int chunksize = min(count, hvsi_write_room(hp->tty));
+	while ((count > 0) && (hvsi_write_room(tty) > 0)) {
+		int chunksize = min(count, hvsi_write_room(tty));
 
 		BUG_ON(hp->n_outbuf < 0);
 		memcpy(hp->outbuf + hp->n_outbuf, source, chunksize);
@@ -1014,19 +989,16 @@ static void hvsi_unthrottle(struct tty_struct *tty)
 {
 	struct hvsi_struct *hp = tty->driver_data;
 	unsigned long flags;
-	int shouldflip = 0;
 
 	pr_debug("%s\n", __func__);
 
 	spin_lock_irqsave(&hp->lock, flags);
 	if (hp->n_throttle) {
-		hvsi_send_overflow(hp);
-		shouldflip = 1;
+		hvsi_send_overflow(hp, tty);
+		tty_flip_buffer_push(tty);
 	}
 	spin_unlock_irqrestore(&hp->lock, flags);
 
-	if (shouldflip)
-		tty_flip_buffer_push(hp->tty);
 
 	h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE);
 }
-- 
1.7.9.2



  parent reply	other threads:[~2012-04-02 11:56 UTC|newest]

Thread overview: 81+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
2012-04-02 11:53 ` [PATCH 01/69] TTY: crisv10, remove unused tmp_buf Jiri Slaby
2012-04-03 11:47   ` Jesper Nilsson
2012-04-02 11:53 ` [PATCH 02/69] TTY: crisv10, initialize tty_port Jiri Slaby
2012-04-03 11:47   ` Jesper Nilsson
2012-04-02 11:53 ` [PATCH 03/69] TTY: deprecate linux/generic_serial.h Jiri Slaby
2012-04-02 11:53 ` [PATCH 04/69] ISDN: i4l, remove cvs crap Jiri Slaby
2012-04-02 11:53 ` [PATCH 05/69] TTY: isdn, remove callout Jiri Slaby
2012-04-02 11:53 ` [PATCH 06/69] TTY: isdn, remove ISDN_ASYNC_* flags Jiri Slaby
2012-04-02 11:53 ` [PATCH 07/69] TTY: isdn, do not play with module refcounts Jiri Slaby
2012-04-02 11:53 ` [PATCH 08/69] TTY: isdn, make some functions readable Jiri Slaby
2012-04-02 11:53 ` [PATCH 09/69] TTY: isdn, remove unused members from modem_info Jiri Slaby
2012-04-02 11:53 ` [PATCH 10/69] TTY: isdn, add tty_port Jiri Slaby
2012-04-02 11:53 ` [PATCH 11/69] TTY: isdn, use open/close_wait from tty_port Jiri Slaby
2012-04-02 11:53 ` [PATCH 12/69] TTY: isdn, use counts " Jiri Slaby
2012-04-02 11:53 ` [PATCH 13/69] TTY: isdn, use tty " Jiri Slaby
2012-04-02 11:53 ` [PATCH 14/69] TTY: isdn, use xmit_buf " Jiri Slaby
2012-04-02 11:53 ` [PATCH 15/69] TTY: isdn, define local tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 16/69] TTY: isdn, use tty_port_close_end helper Jiri Slaby
2012-04-02 11:54 ` [PATCH 17/69] TTY: isdn, define tty_port_operations Jiri Slaby
2012-04-02 11:54 ` [PATCH 18/69] TTY: isdn, use tty_port_block_til_ready helper Jiri Slaby
2012-04-02 11:54 ` [PATCH 19/69] TTY: hso, do not set TTY MAGIC Jiri Slaby
2012-04-02 11:54 ` [PATCH 20/69] TTY: hso, free tty_driver Jiri Slaby
2012-04-02 11:54 ` [PATCH 21/69] TTY: hso, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 22/69] TTY: hso, remove tty NULL checks fro tty->ops Jiri Slaby
2012-04-02 11:54 ` [PATCH 23/69] TTY: hso, use tty from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 24/69] TTY: con3215, centralize allocation Jiri Slaby
2012-04-03  5:56   ` Heiko Carstens
2012-04-02 11:54 ` [PATCH 25/69] TTY: con3215, remove tasklet for tty_wakeup Jiri Slaby
2012-04-03  5:42   ` Heiko Carstens
2012-04-03  7:59     ` Jiri Slaby
2012-04-09 18:27       ` Greg KH
2012-04-09 18:30         ` Jiri Slaby
2012-04-09 19:07           ` Greg KH
2012-04-02 11:54 ` [PATCH 26/69] TTY: con3215, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 27/69] TTY: con3215, use tty from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 28/69] TTY: sclp_tty, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 29/69] TTY: sclp_vt220, " Jiri Slaby
2012-04-02 11:54 ` [PATCH 30/69] TTY: sclp_vt220, remove unused allocation Jiri Slaby
2012-04-02 11:54 ` [PATCH 31/69] TTY: tty3270, move initialization to allocation Jiri Slaby
2012-04-02 11:54 ` [PATCH 32/69] TTY: tty3270, get rid of ugly aliasing Jiri Slaby
2012-04-02 11:54 ` [PATCH 33/69] TTY: tty3270, push tty down to tty3270_do_write Jiri Slaby
2012-04-02 11:54 ` [PATCH 34/69] TTY: tty3270, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 35/69] TTY: bfin_jtag_comm, " Jiri Slaby
2012-04-02 11:54 ` [PATCH 36/69] TTY: bfin_jtag_comm, use tty from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 37/69] TTY: HVC, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 38/69] TTY: HVC, use tty from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 39/69] TTY: HVC, use count " Jiri Slaby
2012-04-02 11:54 ` [PATCH 40/69] TTY: hvcs, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 41/69] TTY: hvcs, use kref from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 42/69] TTY: hvcs, use tty " Jiri Slaby
2012-04-02 11:54 ` [PATCH 43/69] TTY: hvsi, CLOCAL is not in tty->flags Jiri Slaby
2012-04-02 11:54 ` [PATCH 44/69] TTY: hvsi, add tty_port Jiri Slaby
2012-04-02 11:54 ` Jiri Slaby [this message]
2012-04-02 11:54 ` [PATCH 46/69] TTY: hvsi, use tty from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 47/69] TTY: ipwireless, use synchronous hangup Jiri Slaby
2012-04-02 12:42   ` David Sterba
2012-04-02 11:54 ` [PATCH 48/69] TTY: ipwireless, move prints to appropriate places Jiri Slaby
2012-04-02 11:54 ` [PATCH 49/69] TTY: ipwireless, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 50/69] TTY: ipwireless, use tty from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 51/69] TTY: 68328serial, remove serial_state and friends Jiri Slaby
2012-04-03 12:48   ` Geert Uytterhoeven
2012-04-02 11:54 ` [PATCH 52/69] TTY: 68328serial, remove unused stuff from m68k_serial Jiri Slaby
2012-04-02 11:54 ` [PATCH 53/69] TTY: 68328serial, remove garbage Jiri Slaby
2012-04-02 11:54 ` [PATCH 54/69] TTY: 68328serial, use ulong flags for interrupts status Jiri Slaby
2012-04-02 11:54 ` [PATCH 55/69] TTY: 68328serial, remove 68328serial.h Jiri Slaby
2012-04-02 11:54 ` [PATCH 56/69] TTY: 68328serial, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 57/69] TTY: 68328serial, use open/close_wait from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 58/69] TTY: 68328serial, use close_delay/closing_wait " Jiri Slaby
2012-04-02 11:54 ` [PATCH 59/69] TTY: 68328serial, use flags " Jiri Slaby
2012-04-02 11:54 ` [PATCH 60/69] TTY: 68328serial, propagate tty Jiri Slaby
2012-04-02 11:54 ` [PATCH 61/69] TTY: 68328serial, use tty from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 62/69] TTY: 68328serial, use tty_port_block_til_ready Jiri Slaby
2012-04-04 12:25   ` Greg Ungerer
2012-04-02 11:54 ` [PATCH 63/69] TTY: usb/u_serial, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 64/69] TTY: usb/u_serial, use tty from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 65/69] TTY: usb/u_serial use close_wait " Jiri Slaby
2012-04-02 11:54 ` [PATCH 66/69] TTY: rfcomm/tty, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 67/69] TTY: rfcomm/tty, use tty_port refcounting Jiri Slaby
2012-04-02 11:54 ` [PATCH 68/69] TTY: rfcomm/tty, remove work for tty_wakeup Jiri Slaby
2012-04-02 11:54 ` [PATCH 69/69] TTY: rfcomm/tty, use count from tty_port Jiri Slaby

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1333367693-3244-46-git-send-email-jslaby@suse.cz \
    --to=jslaby@suse.cz \
    --cc=alan@linux.intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jirislaby@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).