lkml.org 
[lkml]   [1999]   [Dec]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patches in this message
/
Date
From
Subject[REVISED]Patches to make flipbufs configurable

Hello, Theodore,

The attached file contains the revised Pavel Machek's patches for both
kernels 2.2.x and 2.3.x (the patches were built against 2.2.14pre13 and
2.3.32).

These patches allow drivers to configure bigger flipbuffers in the TTY
structure, while it is backward compatible (i.e., if a driver doesn't
configure this feature, it defaults to the original flipbuf size of
TTY_FLIPBUF_SIZE).

I have tested these patches with a modified Cyclades driver that uses
the feature and they worked fine. As the serial driver and the Rocketport
driver that I superficially tested here worked fine as well, I guess that
the patches really are backward-compatible, i.e., they don't break the
current code.

In the revision process, I moved some memset's around to avoid improper
memory access and included some definitions that Pavel forgot to include
in his original patch.

Please analyze these patches and let me know whether/when you'll include
them in the official TTY driver.

Regards,
Ivan
--- linux/drivers/char/tty_io.c.orig Tue Oct 19 17:14:00 1999
+++ linux/drivers/char/tty_io.c Wed Dec 15 17:32:15 1999
@@ -115,7 +115,7 @@
*/
struct tty_struct * redirect = NULL;

-static void initialize_tty_struct(struct tty_struct *tty);
+static int initialize_tty_struct(struct tty_struct *tty, int);

static ssize_t tty_read(struct file *, char *, size_t, loff_t *);
static ssize_t tty_write(struct file *, const char *, size_t, loff_t *);
@@ -758,7 +758,7 @@
struct tty_struct *tty, *o_tty;
struct termios *tp, **tp_loc, *o_tp, **o_tp_loc;
struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
- struct tty_driver *driver;
+ struct tty_driver *driver;
int retval=0;
int idx;

@@ -790,10 +790,16 @@
tp = o_tp = NULL;
ltp = o_ltp = NULL;

- tty = (struct tty_struct*) get_free_page(GFP_KERNEL);
+ tty = (struct tty_struct*)
+ kmalloc(sizeof(struct tty_struct), GFP_KERNEL);
if(!tty)
goto fail_no_mem;
- initialize_tty_struct(tty);
+
+ memset(tty, 0, sizeof(struct tty_struct));
+ if (initialize_tty_struct(tty, driver->flip_size)) {
+ kfree(tty);
+ goto fail_no_mem;
+ }
tty->device = device;
tty->driver = *driver;

@@ -816,10 +822,17 @@
}

if (driver->type == TTY_DRIVER_TYPE_PTY) {
- o_tty = (struct tty_struct *) get_free_page(GFP_KERNEL);
+ o_tty = (struct tty_struct *)
+ kmalloc(sizeof(struct tty_struct), GFP_KERNEL);
if (!o_tty)
goto free_mem_out;
- initialize_tty_struct(o_tty);
+
+ memset(o_tty, 0, sizeof(struct tty_struct));
+ if (initialize_tty_struct(o_tty, TTY_FLIPBUF_SIZE)) {
+ kfree(o_tty);
+ o_tty = NULL;
+ goto free_mem_out;
+ }
o_tty->device = (kdev_t) MKDEV(driver->other->major,
driver->other->minor_start + idx);
o_tty->driver = *driver->other;
@@ -935,13 +948,16 @@
free_mem_out:
if (o_tp)
kfree_s(o_tp, sizeof(struct termios));
- if (o_tty)
- free_page((unsigned long) o_tty);
+ if (o_tty) {
+ kfree(o_tty->flip.char_buf);
+ kfree(o_tty);
+ }
if (ltp)
kfree_s(ltp, sizeof(struct termios));
if (tp)
kfree_s(tp, sizeof(struct termios));
- free_page((unsigned long) tty);
+ kfree(tty->flip.char_buf);
+ kfree(tty);

fail_no_mem:
retval = -ENOMEM;
@@ -972,7 +988,8 @@
}
o_tty->magic = 0;
(*o_tty->driver.refcount)--;
- free_page((unsigned long) o_tty);
+ kfree(o_tty->flip.char_buf);
+ kfree(o_tty);
}

tty->driver.table[idx] = NULL;
@@ -983,7 +1000,8 @@
}
tty->magic = 0;
(*tty->driver.refcount)--;
- free_page((unsigned long) tty);
+ kfree(tty->flip.char_buf);
+ kfree(tty);
}

/*
@@ -1847,8 +1865,8 @@
return;
}
if (tty->flip.buf_num) {
- cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
- fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
+ cp = tty->flip.char_buf + tty->flip.buf_size;
+ fp = tty->flip.flag_buf + tty->flip.buf_size;
tty->flip.buf_num = 0;

save_flags(flags); cli();
@@ -1860,8 +1878,10 @@
tty->flip.buf_num = 1;

save_flags(flags); cli();
- tty->flip.char_buf_ptr = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
- tty->flip.flag_buf_ptr = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
+ tty->flip.char_buf_ptr = tty->flip.char_buf +
+ tty->flip.buf_size;
+ tty->flip.flag_buf_ptr = tty->flip.flag_buf +
+ tty->flip.buf_size;
}
count = tty->flip.count;
tty->flip.count = 0;
@@ -1925,9 +1945,17 @@
/*
* This subroutine initializes a tty structure.
*/
-static void initialize_tty_struct(struct tty_struct *tty)
+static int initialize_tty_struct(struct tty_struct *tty, int flip_size)
{
memset(tty, 0, sizeof(struct tty_struct));
+ /* There was notice about buffer overrun in original
+ code -- that's why I do +4 */
+ tty->flip.char_buf = kmalloc(flip_size*4 +4, GFP_KERNEL);
+ if (!tty->flip.char_buf)
+ return -ENOMEM;
+
+ tty->flip.flag_buf = tty->flip.char_buf + flip_size*2;
+ tty->flip.buf_size = flip_size;
tty->magic = TTY_MAGIC;
tty->ldisc = ldiscs[N_TTY];
tty->pgrp = -1;
@@ -1940,6 +1968,8 @@
tty->tq_hangup.data = tty;
sema_init(&tty->atomic_read, 1);
sema_init(&tty->atomic_write, 1);
+
+ return 0;
}

/*
@@ -1959,6 +1989,9 @@

if (driver->flags & TTY_DRIVER_INSTALLED)
return 0;
+
+ if (!(driver->flags & TTY_DRIVER_SPECIAL_FLIPSIZE))
+ driver->flip_size = TTY_FLIPBUF_SIZE;

error = register_chrdev(driver->major, driver->name, &tty_fops);
if (error < 0)
--- linux/include/linux/tty.h.orig Wed Dec 15 15:29:44 1999
+++ linux/include/linux/tty.h Tue Nov 23 09:47:04 1999
@@ -130,8 +130,8 @@

/*
* This is the flip buffer used for the tty driver. The buffer is
- * located in the tty structure, and is used as a high speed interface
- * between the tty driver and the tty line discipline.
+ * kmalloced, and is used as a high speed interface between tty driver
+ * and the line discipline.
*/
#define TTY_FLIPBUF_SIZE 512

@@ -142,9 +142,9 @@
unsigned char *flag_buf_ptr;
int count;
int buf_num;
- unsigned char char_buf[2*TTY_FLIPBUF_SIZE];
- char flag_buf[2*TTY_FLIPBUF_SIZE];
- unsigned char slop[4]; /* N.B. bug overwrites buffer by 1 */
+ int buf_size;
+ unsigned char *char_buf;
+ char *flag_buf;
};
/*
* The pty uses char_buf and flag_buf as a contiguous buffer
--- linux/include/linux/tty_driver.h.orig Wed Dec 15 15:29:44 1999
+++ linux/include/linux/tty_driver.h Tue Nov 23 09:41:35 1999
@@ -130,6 +130,7 @@
struct termios init_termios; /* Initial termios */
int flags; /* tty driver flags */
int *refcount; /* for loadable tty drivers */
+ int flip_size; /* flip buffer size */
struct proc_dir_entry *proc_entry; /* /proc fs entry */
struct tty_driver *other; /* only used for the PTY driver */

@@ -197,10 +198,14 @@
* optimize for this case if this flag is set. (Note that there
* is also a promise, if the above case is true, not to signal
* overruns, either.)
+ *
+ * TTY_DRIVER_SPECIAL_FLIPSIZE --- if set, indicates that the driver
+ * will provide the flip buffer size it wishes to use.
*/
#define TTY_DRIVER_INSTALLED 0x0001
#define TTY_DRIVER_RESET_TERMIOS 0x0002
#define TTY_DRIVER_REAL_RAW 0x0004
+#define TTY_DRIVER_SPECIAL_FLIPSIZE 0x0008

/* tty driver types */
#define TTY_DRIVER_TYPE_SYSTEM 0x0001--- linux/drivers/char/tty_io.c.orig Tue Oct 19 10:22:20 1999
+++ linux/drivers/char/tty_io.c Wed Dec 15 17:39:10 1999
@@ -115,7 +115,7 @@
*/
struct tty_struct * redirect = NULL;

-static void initialize_tty_struct(struct tty_struct *tty);
+static int initialize_tty_struct(struct tty_struct *tty, int);

static ssize_t tty_read(struct file *, char *, size_t, loff_t *);
static ssize_t tty_write(struct file *, const char *, size_t, loff_t *);
@@ -766,7 +766,7 @@
struct tty_struct *tty, *o_tty;
struct termios *tp, **tp_loc, *o_tp, **o_tp_loc;
struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
- struct tty_driver *driver;
+ struct tty_driver *driver;
int retval=0;
int idx;

@@ -798,10 +798,16 @@
tp = o_tp = NULL;
ltp = o_ltp = NULL;

- tty = (struct tty_struct*) get_zeroed_page(GFP_KERNEL);
+ tty = (struct tty_struct*)
+ kmalloc(sizeof(struct tty_struct), GFP_KERNEL);
if(!tty)
goto fail_no_mem;
- initialize_tty_struct(tty);
+
+ memset(tty, 0, sizeof(struct tty_struct));
+ if (initialize_tty_struct(tty, driver->flip_size)) {
+ kfree(tty);
+ goto fail_no_mem;
+ }
tty->device = device;
tty->driver = *driver;

@@ -824,10 +830,17 @@
}

if (driver->type == TTY_DRIVER_TYPE_PTY) {
- o_tty = (struct tty_struct *) get_zeroed_page(GFP_KERNEL);
+ o_tty = (struct tty_struct *)
+ kmalloc(sizeof(struct tty_struct), GFP_KERNEL);
if (!o_tty)
goto free_mem_out;
- initialize_tty_struct(o_tty);
+
+ memset(o_tty, 0, sizeof(struct tty_struct));
+ if (initialize_tty_struct(o_tty, TTY_FLIPBUF_SIZE)) {
+ kfree(o_tty);
+ o_tty = NULL;
+ goto free_mem_out;
+ }
o_tty->device = (kdev_t) MKDEV(driver->other->major,
driver->other->minor_start + idx);
o_tty->driver = *driver->other;
@@ -943,13 +956,16 @@
free_mem_out:
if (o_tp)
kfree_s(o_tp, sizeof(struct termios));
- if (o_tty)
- free_page((unsigned long) o_tty);
+ if (o_tty) {
+ kfree(o_tty->flip.char_buf);
+ kfree(o_tty);
+ }
if (ltp)
kfree_s(ltp, sizeof(struct termios));
if (tp)
kfree_s(tp, sizeof(struct termios));
- free_page((unsigned long) tty);
+ kfree(tty->flip.char_buf);
+ kfree(tty);

fail_no_mem:
retval = -ENOMEM;
@@ -980,7 +996,8 @@
}
o_tty->magic = 0;
(*o_tty->driver.refcount)--;
- free_page((unsigned long) o_tty);
+ kfree(o_tty->flip.char_buf);
+ kfree(o_tty);
}

tty->driver.table[idx] = NULL;
@@ -991,7 +1008,8 @@
}
tty->magic = 0;
(*tty->driver.refcount)--;
- free_page((unsigned long) tty);
+ kfree(tty->flip.char_buf);
+ kfree(tty);
}

/*
@@ -1862,8 +1880,8 @@
return;
}
if (tty->flip.buf_num) {
- cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
- fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
+ cp = tty->flip.char_buf + tty->flip.buf_size;
+ fp = tty->flip.flag_buf + tty->flip.buf_size;
tty->flip.buf_num = 0;

save_flags(flags); cli();
@@ -1875,8 +1893,10 @@
tty->flip.buf_num = 1;

save_flags(flags); cli();
- tty->flip.char_buf_ptr = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
- tty->flip.flag_buf_ptr = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
+ tty->flip.char_buf_ptr = tty->flip.char_buf +
+ tty->flip.buf_size;
+ tty->flip.flag_buf_ptr = tty->flip.flag_buf +
+ tty->flip.buf_size;
}
count = tty->flip.count;
tty->flip.count = 0;
@@ -1940,9 +1960,17 @@
/*
* This subroutine initializes a tty structure.
*/
-static void initialize_tty_struct(struct tty_struct *tty)
+static int initialize_tty_struct(struct tty_struct *tty, int flip_size)
{
memset(tty, 0, sizeof(struct tty_struct));
+ /* There was notice about buffer overrun in original
+ code -- that's why I do +4 */
+ tty->flip.char_buf = kmalloc(flip_size*4 +4, GFP_KERNEL);
+ if (!tty->flip.char_buf)
+ return -ENOMEM;
+
+ tty->flip.flag_buf = tty->flip.char_buf + flip_size*2;
+ tty->flip.buf_size = flip_size;
tty->magic = TTY_MAGIC;
tty->ldisc = ldiscs[N_TTY];
tty->pgrp = -1;
@@ -1957,6 +1985,8 @@
tty->tq_hangup.data = tty;
sema_init(&tty->atomic_read, 1);
INIT_LIST_HEAD(&tty->tty_files);
+
+ return 0;
}

/*
@@ -1976,6 +2006,9 @@

if (driver->flags & TTY_DRIVER_INSTALLED)
return 0;
+
+ if (!(driver->flags & TTY_DRIVER_SPECIAL_FLIPSIZE))
+ driver->flip_size = TTY_FLIPBUF_SIZE;

error = register_chrdev(driver->major, driver->name, &tty_fops);
if (error < 0)
--- linux/include/linux/tty.h.orig Tue Dec 14 00:55:10 1999
+++ linux/include/linux/tty.h Wed Dec 15 17:40:47 1999
@@ -126,8 +126,8 @@

/*
* This is the flip buffer used for the tty driver. The buffer is
- * located in the tty structure, and is used as a high speed interface
- * between the tty driver and the tty line discipline.
+ * kmalloced, and is used as a high speed interface between tty driver
+ * and the line discipline.
*/
#define TTY_FLIPBUF_SIZE 512

@@ -138,9 +138,9 @@
unsigned char *flag_buf_ptr;
int count;
int buf_num;
- unsigned char char_buf[2*TTY_FLIPBUF_SIZE];
- char flag_buf[2*TTY_FLIPBUF_SIZE];
- unsigned char slop[4]; /* N.B. bug overwrites buffer by 1 */
+ int buf_size;
+ unsigned char *char_buf;
+ char *flag_buf;
};
/*
* The pty uses char_buf and flag_buf as a contiguous buffer
--- linux/include/linux/tty_driver.h.orig Tue Dec 14 00:55:09 1999
+++ linux/include/linux/tty_driver.h Wed Dec 15 17:42:22 1999
@@ -130,6 +130,7 @@
struct termios init_termios; /* Initial termios */
int flags; /* tty driver flags */
int *refcount; /* for loadable tty drivers */
+ int flip_size; /* flip buffer size */
struct proc_dir_entry *proc_entry; /* /proc fs entry */
struct tty_driver *other; /* only used for the PTY driver */

@@ -197,10 +198,14 @@
* optimize for this case if this flag is set. (Note that there
* is also a promise, if the above case is true, not to signal
* overruns, either.)
+ *
+ * TTY_DRIVER_SPECIAL_FLIPSIZE --- if set, indicates that the driver
+ * will provide the flip buffer size it wishes to use.
*/
#define TTY_DRIVER_INSTALLED 0x0001
#define TTY_DRIVER_RESET_TERMIOS 0x0002
#define TTY_DRIVER_REAL_RAW 0x0004
+#define TTY_DRIVER_SPECIAL_FLIPSIZE 0x0008

/* tty driver types */
#define TTY_DRIVER_TYPE_SYSTEM 0x0001
\
 
 \ /
  Last update: 2005-03-22 13:55    [W:0.802 / U:0.368 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site