2010-02-17 13:30:31

by Alan

[permalink] [raw]
Subject: [PATCH 1/5] tty: Add a function to insert a string of characters with the same flag

The USB drivers often want to insert a series of bytes all with the same
flag set - provide a helper for this case.

Signed-off-by: Alan Cox <[email protected]>
---

drivers/char/tty_buffer.c | 12 +++++++-----
include/linux/tty_flip.h | 7 ++++++-
2 files changed, 13 insertions(+), 6 deletions(-)


diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c
index 8402eda..af8d977 100644
--- a/drivers/char/tty_buffer.c
+++ b/drivers/char/tty_buffer.c
@@ -231,9 +231,10 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size)
EXPORT_SYMBOL_GPL(tty_buffer_request_room);

/**
- * tty_insert_flip_string - Add characters to the tty buffer
+ * tty_insert_flip_string_fixed_flag - Add characters to the tty buffer
* @tty: tty structure
* @chars: characters
+ * @flag: flag value for each character
* @size: size
*
* Queue a series of bytes to the tty buffering. All the characters
@@ -242,18 +243,19 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_room);
* Locking: Called functions may take tty->buf.lock
*/

-int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars,
- size_t size)
+int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
+ const unsigned char *chars, char flag, size_t size)
{
int copied = 0;
do {
+ int goal = min(size - copied, TTY_BUFFER_PAGE);
int space = tty_buffer_request_room(tty, goal);
struct tty_buffer *tb = tty->buf.tail;
/* If there is no space then tb may be NULL */
if (unlikely(space == 0))
break;
memcpy(tb->char_buf_ptr + tb->used, chars, space);
- memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
+ memset(tb->flag_buf_ptr + tb->used, flag, space);
tb->used += space;
copied += space;
chars += space;
@@ -262,7 +264,7 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars,
} while (unlikely(size > copied));
return copied;
}
-EXPORT_SYMBOL(tty_insert_flip_string);
+EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag);

/**
* tty_insert_flip_string_flags - Add characters to the tty buffer
diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h
index eb677cf..9239d03 100644
--- a/include/linux/tty_flip.h
+++ b/include/linux/tty_flip.h
@@ -2,8 +2,8 @@
#define _LINUX_TTY_FLIP_H

extern int tty_buffer_request_room(struct tty_struct *tty, size_t size);
-extern int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, size_t size);
extern int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size);
+extern int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, const unsigned char *chars, char flag, size_t size);
extern int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size);
extern int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size);
void tty_schedule_flip(struct tty_struct *tty);
@@ -20,4 +20,9 @@ static inline int tty_insert_flip_char(struct tty_struct *tty,
return tty_insert_flip_string_flags(tty, &ch, &flag, 1);
}

+static inline int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, size_t size)
+{
+ return tty_insert_flip_string_fixed_flag(tty, chars, TTY_NORMAL, size);
+}
+
#endif /* _LINUX_TTY_FLIP_H */


2010-02-17 13:30:49

by Alan

[permalink] [raw]
Subject: [PATCH 2/5] tty: Prune uses of tty_request_room in the USB layer

We have lots of callers that do not need to do this in the first place.
Remove the calls as they both cost CPU and for big buffers can mess up the
multi-page allocation avoidance.

Signed-off-by: Alan Cox <[email protected]>
---

drivers/usb/serial/ark3116.c | 1 -
drivers/usb/serial/cyberjack.c | 1 -
drivers/usb/serial/cypress_m8.c | 10 +++-------
drivers/usb/serial/digi_acceleport.c | 13 ++-----------
drivers/usb/serial/empeg.c | 1 -
drivers/usb/serial/garmin_gps.c | 1 -
drivers/usb/serial/io_edgeport.c | 19 +++++++------------
drivers/usb/serial/io_ti.c | 1 -
drivers/usb/serial/ipaq.c | 1 -
drivers/usb/serial/ipw.c | 1 -
drivers/usb/serial/ir-usb.c | 6 ++----
drivers/usb/serial/kl5kusb105.c | 1 -
drivers/usb/serial/kobil_sct.c | 1 -
drivers/usb/serial/mos7720.c | 1 -
drivers/usb/serial/mos7840.c | 1 -
drivers/usb/serial/navman.c | 1 -
drivers/usb/serial/opticon.c | 11 +++--------
drivers/usb/serial/option.c | 1 -
drivers/usb/serial/pl2303.c | 1 -
drivers/usb/serial/sierra.c | 1 -
drivers/usb/serial/spcp8x5.c | 6 ++----
drivers/usb/serial/symbolserial.c | 10 ++--------
drivers/usb/serial/ti_usb_3410_5052.c | 3 +--
drivers/usb/serial/visor.c | 10 +++-------
24 files changed, 25 insertions(+), 78 deletions(-)


diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index 1f75fac..547c944 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -733,7 +733,6 @@ static void ark3116_read_bulk_callback(struct urb *urb)

tty = tty_port_tty_get(&port->port);
if (tty) {
- tty_buffer_request_room(tty, urb->actual_length + 1);
/* overrun is special, not associated with a char */
if (unlikely(lsr & UART_LSR_OE))
tty_insert_flip_char(tty, 0, TTY_OVERRUN);
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 23c8bd6..ba4ae6c 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -395,7 +395,6 @@ static void cyberjack_read_bulk_callback(struct urb *urb)
return;
}
if (urb->actual_length) {
- tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 3370dc4..47c5a0d 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -1307,13 +1307,9 @@ static void cypress_read_int_callback(struct urb *urb)
spin_unlock_irqrestore(&priv->lock, flags);

/* process read if there is data other than line status */
- if (tty && (bytes > i)) {
- bytes = tty_buffer_request_room(tty, bytes);
- for (; i < bytes ; ++i) {
- dbg("pushing byte number %d - %d - %c", i, data[i],
- data[i]);
- tty_insert_flip_char(tty, data[i], tty_flag);
- }
+ if (tty && bytes > i) {
+ tty_insert_flip_string_fixed_flag(tty, data + i,
+ bytes - i, tty_flag);
tty_flip_buffer_push(tty);
}

diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 3b63484..3817228 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -1658,7 +1658,6 @@ static int digi_read_inb_callback(struct urb *urb)
int port_status = ((unsigned char *)urb->transfer_buffer)[2];
unsigned char *data = ((unsigned char *)urb->transfer_buffer) + 3;
int flag, throttled;
- int i;
int status = urb->status;

/* do not process callbacks on closed ports */
@@ -1705,17 +1704,9 @@ static int digi_read_inb_callback(struct urb *urb)

/* data length is len-1 (one byte of len is port_status) */
--len;
-
- len = tty_buffer_request_room(tty, len);
if (len > 0) {
- /* Hot path */
- if (flag == TTY_NORMAL)
- tty_insert_flip_string(tty, data, len);
- else {
- for (i = 0; i < len; i++)
- tty_insert_flip_char(tty,
- data[i], flag);
- }
+ tty_insert_flip_string_fixed_flag(tty, data, len,
+ flag);
tty_flip_buffer_push(tty);
}
}
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index d02e604..5f740a1 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -346,7 +346,6 @@ static void empeg_read_bulk_callback(struct urb *urb)
tty = tty_port_tty_get(&port->port);

if (urb->actual_length) {
- tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
bytes_in += urb->actual_length;
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 6bbedfb..a42b29a 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -271,7 +271,6 @@ static void send_to_tty(struct usb_serial_port *port,
usb_serial_debug_data(debug, &port->dev,
__func__, actual_length, data);

- tty_buffer_request_room(tty, actual_length);
tty_insert_flip_string(tty, data, actual_length);
tty_flip_buffer_push(tty);
}
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 1467755..e40ec6d 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -2055,18 +2055,13 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty,
{
int cnt;

- do {
- cnt = tty_buffer_request_room(tty, length);
- if (cnt < length) {
- dev_err(dev, "%s - dropping data, %d bytes lost\n",
- __func__, length - cnt);
- if (cnt == 0)
- break;
- }
- tty_insert_flip_string(tty, data, cnt);
- data += cnt;
- length -= cnt;
- } while (length > 0);
+ cnt = tty_insert_flip_string(tty, data, length);
+ if (cnt < length) {
+ dev_err(dev, "%s - dropping data, %d bytes lost\n",
+ __func__, length - cnt);
+ }
+ data += cnt;
+ length -= cnt;

tty_flip_buffer_push(tty);
}
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 8f0aa64..b84befa 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -1820,7 +1820,6 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty,
{
int queued;

- tty_buffer_request_room(tty, length);
queued = tty_insert_flip_string(tty, data, length);
if (queued < length)
dev_err(dev, "%s - dropping data, %d bytes lost\n",
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index d6231c3..3fea929 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -747,7 +747,6 @@ static void ipaq_read_bulk_callback(struct urb *urb)

tty = tty_port_tty_get(&port->port);
if (tty && urb->actual_length) {
- tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
bytes_in += urb->actual_length;
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index c0afa7a..e1d0784 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -172,7 +172,6 @@ static void ipw_read_bulk_callback(struct urb *urb)

tty = tty_port_tty_get(&port->port);
if (tty && urb->actual_length) {
- tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index fc2ab81..c3e5d50 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -462,10 +462,8 @@ static void ir_read_bulk_callback(struct urb *urb)
usb_serial_debug_data(debug, &port->dev, __func__,
urb->actual_length, data);
tty = tty_port_tty_get(&port->port);
- if (tty_buffer_request_room(tty, urb->actual_length - 1)) {
- tty_insert_flip_string(tty, data+1, urb->actual_length - 1);
- tty_flip_buffer_push(tty);
- }
+ tty_insert_flip_string(tty, data+1, urb->actual_length - 1);
+ tty_flip_buffer_push(tty);
tty_kref_put(tty);

/*
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index 2dbe22a..8eef91b 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -699,7 +699,6 @@ static void klsi_105_read_bulk_callback(struct urb *urb)
bytes_sent = urb->actual_length - 2;
}

- tty_buffer_request_room(tty, bytes_sent);
tty_insert_flip_string(tty, data + 2, bytes_sent);
tty_flip_buffer_push(tty);
tty_kref_put(tty);
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index fc78553..c113a2a 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -388,7 +388,6 @@ static void kobil_read_int_callback(struct urb *urb)
*/
/* END DEBUG */

- tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index e0aa031..900cfb8 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -290,7 +290,6 @@ static void mos7720_bulk_in_callback(struct urb *urb)

tty = tty_port_tty_get(&port->port);
if (tty && urb->actual_length) {
- tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index c89a89c..2fda1c0 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -764,7 +764,6 @@ static void mos7840_bulk_in_callback(struct urb *urb)
if (urb->actual_length) {
tty = tty_port_tty_get(&mos7840_port->port->port);
if (tty) {
- tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
dbg(" %s ", data);
tty_flip_buffer_push(tty);
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c
index efa61bc..04a6cbb 100644
--- a/drivers/usb/serial/navman.c
+++ b/drivers/usb/serial/navman.c
@@ -66,7 +66,6 @@ static void navman_read_int_callback(struct urb *urb)

tty = tty_port_tty_get(&port->port);
if (tty && urb->actual_length) {
- tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 05b3ac4..4972197 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -55,7 +55,6 @@ static void opticon_bulk_callback(struct urb *urb)
int status = urb->status;
struct tty_struct *tty;
int result;
- int available_room = 0;
int data_length;

dbg("%s - port %d", __func__, port->number);
@@ -96,13 +95,9 @@ static void opticon_bulk_callback(struct urb *urb)
/* real data, send it to the tty layer */
tty = tty_port_tty_get(&port->port);
if (tty) {
- available_room = tty_buffer_request_room(tty,
- data_length);
- if (available_room) {
- tty_insert_flip_string(tty, data,
- available_room);
- tty_flip_buffer_push(tty);
- }
+ tty_insert_flip_string(tty, data,
+ data_length);
+ tty_flip_buffer_push(tty);
tty_kref_put(tty);
}
} else {
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 51b0beb..ea92a6a 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -964,7 +964,6 @@ static void option_indat_callback(struct urb *urb)
} else {
tty = tty_port_tty_get(&port->port);
if (urb->actual_length) {
- tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
} else
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 767000c..a3e5a56 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -1042,7 +1042,6 @@ static void pl2303_push_data(struct tty_struct *tty,
tty_flag = TTY_FRAME;
dbg("%s - tty_flag = %d", __func__, tty_flag);

- tty_buffer_request_room(tty, urb->actual_length + 1);
/* overrun is special, not associated with a char */
if (line_status & UART_OVERRUN_ERROR)
tty_insert_flip_char(tty, 0, TTY_OVERRUN);
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index bb0d56c..9ff8c65 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -605,7 +605,6 @@ static void sierra_indat_callback(struct urb *urb)
if (urb->actual_length) {
tty = tty_port_tty_get(&port->port);

- tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);

diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index ebd1688..5efb5f0 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -677,7 +677,6 @@ static void spcp8x5_read_bulk_callback(struct urb *urb)
struct tty_struct *tty;
unsigned char *data = urb->transfer_buffer;
unsigned long flags;
- int i;
int result = urb->status;
u8 status;
char tty_flag;
@@ -726,12 +725,11 @@ static void spcp8x5_read_bulk_callback(struct urb *urb)

tty = tty_port_tty_get(&port->port);
if (tty && urb->actual_length) {
- tty_buffer_request_room(tty, urb->actual_length + 1);
/* overrun is special, not associated with a char */
if (status & UART_OVERRUN_ERROR)
tty_insert_flip_char(tty, 0, TTY_OVERRUN);
- for (i = 0; i < urb->actual_length; ++i)
- tty_insert_flip_char(tty, data[i], tty_flag);
+ tty_insert_flip_string_fixed_flag(tty, data,
+ urb->actual_length, tty_flag);
tty_flip_buffer_push(tty);
}
tty_kref_put(tty);
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c
index bd0fd6e..ee190cc 100644
--- a/drivers/usb/serial/symbolserial.c
+++ b/drivers/usb/serial/symbolserial.c
@@ -51,7 +51,6 @@ static void symbol_int_callback(struct urb *urb)
int status = urb->status;
struct tty_struct *tty;
int result;
- int available_room = 0;
int data_length;

dbg("%s - port %d", __func__, port->number);
@@ -89,13 +88,8 @@ static void symbol_int_callback(struct urb *urb)
*/
tty = tty_port_tty_get(&port->port);
if (tty) {
- available_room = tty_buffer_request_room(tty,
- data_length);
- if (available_room) {
- tty_insert_flip_string(tty, &data[1],
- available_room);
- tty_flip_buffer_push(tty);
- }
+ tty_insert_flip_string(tty, &data[1], data_length);
+ tty_flip_buffer_push(tty);
tty_kref_put(tty);
}
} else {
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 1e9dc88..0afe5c7 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -1271,14 +1271,13 @@ static void ti_recv(struct device *dev, struct tty_struct *tty,
int cnt;

do {
- cnt = tty_buffer_request_room(tty, length);
+ cnt = tty_insert_flip_string(tty, data, length);
if (cnt < length) {
dev_err(dev, "%s - dropping data, %d bytes lost\n",
__func__, length - cnt);
if (cnt == 0)
break;
}
- tty_insert_flip_string(tty, data, cnt);
tty_flip_buffer_push(tty);
data += cnt;
length -= cnt;
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 178e4d9..99eb983 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -503,13 +503,9 @@ static void visor_read_bulk_callback(struct urb *urb)
if (urb->actual_length) {
tty = tty_port_tty_get(&port->port);
if (tty) {
- available_room = tty_buffer_request_room(tty,
- urb->actual_length);
- if (available_room) {
- tty_insert_flip_string(tty, data,
- available_room);
- tty_flip_buffer_push(tty);
- }
+ tty_insert_flip_string(tty, data,
+ urb->actual_length);
+ tty_flip_buffer_push(tty);
tty_kref_put(tty);
}
spin_lock(&priv->lock);

2010-02-17 13:30:58

by Alan

[permalink] [raw]
Subject: [PATCH 3/5] tty: sort out the request_room handling for whiteheat

This driver has its own (surplus) backup queue system which wants removing
from the receive overflow logic.

Do this at the same time as removing the request_room logic

Signed-off-by: Alan Cox <[email protected]>
---

drivers/usb/serial/whiteheat.c | 18 +++---------------
1 files changed, 3 insertions(+), 15 deletions(-)


diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index e89e0d5..12ed820 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -1492,21 +1492,9 @@ static void rx_data_softint(struct work_struct *work)
wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
urb = wrap->urb;

- if (tty && urb->actual_length) {
- int len = tty_buffer_request_room(tty,
- urb->actual_length);
- /* This stuff can go away now I suspect */
- if (unlikely(len < urb->actual_length)) {
- spin_lock_irqsave(&info->lock, flags);
- list_add(tmp, &info->rx_urb_q);
- spin_unlock_irqrestore(&info->lock, flags);
- tty_flip_buffer_push(tty);
- schedule_work(&info->rx_work);
- goto out;
- }
- tty_insert_flip_string(tty, urb->transfer_buffer, len);
- sent += len;
- }
+ if (tty && urb->actual_length)
+ sent += tty_insert_flip_string(tty,
+ urb->transfer_buffer, urb->actual_length);

urb->dev = port->serial->dev;
result = usb_submit_urb(urb, GFP_ATOMIC);

2010-02-17 13:31:09

by Alan

[permalink] [raw]
Subject: [PATCH 4/5] tty: kill request_room for USB ACM class

Signed-off-by: Alan Cox <[email protected]>
---

drivers/usb/class/cdc-acm.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)


diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 5155ff2..95a18e5 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -428,7 +428,6 @@ next_buffer:
throttled = acm->throttle;
spin_unlock_irqrestore(&acm->throttle_lock, flags);
if (!throttled) {
- tty_buffer_request_room(tty, buf->size);
tty_insert_flip_string(tty, buf->base, buf->size);
tty_flip_buffer_push(tty);
} else {

2010-02-17 13:31:19

by Alan

[permalink] [raw]
Subject: [PATCH 5/5] tty: Fix up char drivers request_room usage

We can't change them all but quite a few misuse it.

Signed-off-by: Alan Cox <[email protected]>
---

drivers/char/nozomi.c | 2 --
drivers/char/serial167.c | 3 +--
drivers/char/specialix.c | 2 --
drivers/serial/icom.c | 1 -
drivers/serial/ioc3_serial.c | 3 +--
5 files changed, 2 insertions(+), 9 deletions(-)


diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c
index 584910f..a3f32a1 100644
--- a/drivers/char/nozomi.c
+++ b/drivers/char/nozomi.c
@@ -853,8 +853,6 @@ static int receive_data(enum port_type index, struct nozomi *dc)
goto put;
}

- tty_buffer_request_room(tty, size);
-
while (size > 0) {
read_mem32((u32 *) buf, addr + offset, RECEIVE_BUF_MAX);

diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index aee3c0d..1ec3d5c 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -658,8 +658,7 @@ static irqreturn_t cd2401_rx_interrupt(int irq, void *dev_id)
info->mon.char_max = char_count;
info->mon.char_last = char_count;
#endif
- len = tty_buffer_request_room(tty, char_count);
- while (len--) {
+ while (char_count--) {
data = base_addr[CyRDR];
tty_insert_flip_char(tty, data, TTY_NORMAL);
#ifdef CYCLOM_16Y_HACK
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 268e17f..07ac14d 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -646,8 +646,6 @@ static void sx_receive(struct specialix_board *bp)
dprintk(SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
port->hits[count > 8 ? 9 : count]++;

- tty_buffer_request_room(tty, count);
-
while (count--)
tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL);
tty_flip_buffer_push(tty);
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index 6e715b7..53a4682 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -751,7 +751,6 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
trace(icom_port, "FID_STATUS", status);
count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);

- count = tty_buffer_request_room(tty, count);
trace(icom_port, "RCV_COUNT", count);

trace(icom_port, "REAL_COUNT", count);
diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c
index 85dc041..23ba6b4 100644
--- a/drivers/serial/ioc3_serial.c
+++ b/drivers/serial/ioc3_serial.c
@@ -1411,8 +1411,7 @@ static int receive_chars(struct uart_port *the_port)
read_count = do_read(the_port, ch, MAX_CHARS);
if (read_count > 0) {
flip = 1;
- read_room = tty_buffer_request_room(tty, read_count);
- tty_insert_flip_string(tty, ch, read_room);
+ read_room = tty_insert_flip_string(tty, ch, read_count);
the_port->icount.rx += read_count;
}
spin_unlock_irqrestore(&the_port->lock, pflags);

2010-02-26 23:03:27

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH 1/5] tty: Add a function to insert a string of characters with the same flag

On Wed, Feb 17, 2010 at 01:06:30PM +0000, Alan Cox wrote:
> The USB drivers often want to insert a series of bytes all with the same
> flag set - provide a helper for this case.
>
> Signed-off-by: Alan Cox <[email protected]>
> ---
>
> drivers/char/tty_buffer.c | 12 +++++++-----
> include/linux/tty_flip.h | 7 ++++++-
> 2 files changed, 13 insertions(+), 6 deletions(-)
>
>
> diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c
> index 8402eda..af8d977 100644
> --- a/drivers/char/tty_buffer.c
> +++ b/drivers/char/tty_buffer.c
> @@ -231,9 +231,10 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size)
> EXPORT_SYMBOL_GPL(tty_buffer_request_room);
>
> /**
> - * tty_insert_flip_string - Add characters to the tty buffer
> + * tty_insert_flip_string_fixed_flag - Add characters to the tty buffer
> * @tty: tty structure
> * @chars: characters
> + * @flag: flag value for each character
> * @size: size
> *
> * Queue a series of bytes to the tty buffering. All the characters
> @@ -242,18 +243,19 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_room);
> * Locking: Called functions may take tty->buf.lock
> */
>
> -int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars,
> - size_t size)
> +int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
> + const unsigned char *chars, char flag, size_t size)
> {
> int copied = 0;
> do {
> + int goal = min(size - copied, TTY_BUFFER_PAGE);

This variable isn't used in this function.

> int space = tty_buffer_request_room(tty, goal);
> struct tty_buffer *tb = tty->buf.tail;
> /* If there is no space then tb may be NULL */
> if (unlikely(space == 0))
> break;
> memcpy(tb->char_buf_ptr + tb->used, chars, space);
> - memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
> + memset(tb->flag_buf_ptr + tb->used, flag, space);

Should you have "goal" here instead of "space"?

thanks,

greg k-h

2010-02-27 14:46:02

by Christopher Curtis

[permalink] [raw]
Subject: Re: [PATCH 1/5] tty: Add a function to insert a string of characters with the same flag

On Fri, Feb 26, 2010 at 5:11 PM, Greg KH <[email protected]> wrote:
>
> On Wed, Feb 17, 2010 at 01:06:30PM +0000, Alan Cox wrote:
> > The USB drivers often want to insert a series of bytes all with the same
> > flag set - provide a helper for this case.
> >
> > Signed-off-by: Alan Cox <[email protected]>
> > ---
> >
> > ?drivers/char/tty_buffer.c | ? 12 +++++++-----
> > ?include/linux/tty_flip.h ?| ? ?7 ++++++-
> > ?2 files changed, 13 insertions(+), 6 deletions(-)
> >
> >
> > diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c
> > index 8402eda..af8d977 100644
> > --- a/drivers/char/tty_buffer.c
> > +++ b/drivers/char/tty_buffer.c
> > @@ -231,9 +231,10 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size)
> > ?EXPORT_SYMBOL_GPL(tty_buffer_request_room);
> >
> > ?/**
> > - * ? tty_insert_flip_string ?- ? ? ? Add characters to the tty buffer
> > + * ? tty_insert_flip_string_fixed_flag - Add characters to the tty buffer
> > ? * ? @tty: tty structure
> > ? * ? @chars: characters
> > + * ? @flag: flag value for each character
> > ? * ? @size: size
> > ? *
> > ? * ? Queue a series of bytes to the tty buffering. All the characters
> > @@ -242,18 +243,19 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_room);
> > ? * ? Locking: Called functions may take tty->buf.lock
> > ? */
> >
> > -int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars,
> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? size_t size)
> > +int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
> > + ? ? ? ? ? ? const unsigned char *chars, char flag, size_t size)
> > ?{
> > ? ? ? int copied = 0;
> > ? ? ? do {
> > + ? ? ? ? ? ? int goal = min(size - copied, TTY_BUFFER_PAGE);
>
> This variable isn't used in this function.
>
> > ? ? ? ? ? ? ? int space = tty_buffer_request_room(tty, goal);

It is used on the next line; it would appear to be a local scope alias
for some other 'goal'...?

Chris

2010-02-27 18:58:32

by Alan

[permalink] [raw]
Subject: Re: [PATCH 1/5] tty: Add a function to insert a string of characters with the same flag

On Fri, 26 Feb 2010 14:11:00 -0800
Greg KH <[email protected]> wrote:

> On Wed, Feb 17, 2010 at 01:06:30PM +0000, Alan Cox wrote:
> > The USB drivers often want to insert a series of bytes all with the same
> > flag set - provide a helper for this case.

Thats the original set of patches I sent you - there was a second set
which cleaned up the stuff which leaked from one patch to the next or did
those vanish into the department of email oblivion somewhere ?

Will take a look at it when I get some time and see whats up.

Alan

2010-02-27 19:32:12

by Alan

[permalink] [raw]
Subject: Re: [PATCH 1/5] tty: Add a function to insert a string of characters with the same flag

Was it really the 17th I sent the second set out - apparently so - so
ignore the first email, this is the correct patch set.

> > +int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
> > + const unsigned char *chars, char flag, size_t size)
> > {
> > int copied = 0;
> > do {
> > + int goal = min(size - copied, TTY_BUFFER_PAGE);
>
> This variable isn't used in this function.
>
> > int space = tty_buffer_request_room(tty, goal);

Its used here. The logic basically is

goal = { I want a buffer to hold "size - copied"
{ I want it to fit in one page

space = what I get back

we copy space and move on based on what we get back, so it looks correct
to me.

> > memcpy(tb->char_buf_ptr + tb->used, chars, space);
> > - memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
> > + memset(tb->flag_buf_ptr + tb->used, flag, space);
>
> Should you have "goal" here instead of "space"?

No because we could ask for say 500 and get 250 back, we then want to
copy 250.


Alan

2010-02-27 23:37:46

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH 1/5] tty: Add a function to insert a string of characters with the same flag

On Sat, Feb 27, 2010 at 07:02:12PM +0000, Alan Cox wrote:
> On Fri, 26 Feb 2010 14:11:00 -0800
> Greg KH <[email protected]> wrote:
>
> > On Wed, Feb 17, 2010 at 01:06:30PM +0000, Alan Cox wrote:
> > > The USB drivers often want to insert a series of bytes all with the same
> > > flag set - provide a helper for this case.
>
> Thats the original set of patches I sent you - there was a second set
> which cleaned up the stuff which leaked from one patch to the next or did
> those vanish into the department of email oblivion somewhere ?

No, I saw them after writing this, and I applied that series instead.
It should all be good now, sorry for the noise.

greg k-h