aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/n_tty.c29
-rw-r--r--drivers/char/tty_io.c43
-rw-r--r--include/linux/tty_driver.h9
-rw-r--r--include/linux/tty_ldisc.h7
4 files changed, 69 insertions, 19 deletions
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 6ac3ca4c723c..b3d4ccc33a47 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -1544,21 +1544,18 @@ static unsigned int normal_poll(struct tty_struct * tty, struct file * file, pol
1544} 1544}
1545 1545
1546struct tty_ldisc tty_ldisc_N_TTY = { 1546struct tty_ldisc tty_ldisc_N_TTY = {
1547 TTY_LDISC_MAGIC, /* magic */ 1547 .magic = TTY_LDISC_MAGIC,
1548 "n_tty", /* name */ 1548 .name = "n_tty",
1549 0, /* num */ 1549 .open = n_tty_open,
1550 0, /* flags */ 1550 .close = n_tty_close,
1551 n_tty_open, /* open */ 1551 .flush_buffer = n_tty_flush_buffer,
1552 n_tty_close, /* close */ 1552 .chars_in_buffer = n_tty_chars_in_buffer,
1553 n_tty_flush_buffer, /* flush_buffer */ 1553 .read = read_chan,
1554 n_tty_chars_in_buffer, /* chars_in_buffer */ 1554 .write = write_chan,
1555 read_chan, /* read */ 1555 .ioctl = n_tty_ioctl,
1556 write_chan, /* write */ 1556 .set_termios = n_tty_set_termios,
1557 n_tty_ioctl, /* ioctl */ 1557 .poll = normal_poll,
1558 n_tty_set_termios, /* set_termios */ 1558 .receive_buf = n_tty_receive_buf,
1559 normal_poll, /* poll */ 1559 .write_wakeup = n_tty_write_wakeup
1560 NULL, /* hangup */
1561 n_tty_receive_buf, /* receive_buf */
1562 n_tty_write_wakeup /* write_wakeup */
1563}; 1560};
1564 1561
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index fc662e4ce58a..fe62c2170d01 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -151,6 +151,12 @@ static int tty_open(struct inode *, struct file *);
151static int tty_release(struct inode *, struct file *); 151static int tty_release(struct inode *, struct file *);
152int tty_ioctl(struct inode * inode, struct file * file, 152int tty_ioctl(struct inode * inode, struct file * file,
153 unsigned int cmd, unsigned long arg); 153 unsigned int cmd, unsigned long arg);
154#ifdef CONFIG_COMPAT
155static long tty_compat_ioctl(struct file * file, unsigned int cmd,
156 unsigned long arg);
157#else
158#define tty_compat_ioctl NULL
159#endif
154static int tty_fasync(int fd, struct file * filp, int on); 160static int tty_fasync(int fd, struct file * filp, int on);
155static void release_tty(struct tty_struct *tty, int idx); 161static void release_tty(struct tty_struct *tty, int idx);
156static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); 162static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
@@ -1143,8 +1149,8 @@ static unsigned int hung_up_tty_poll(struct file * filp, poll_table * wait)
1143 return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM; 1149 return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM;
1144} 1150}
1145 1151
1146static int hung_up_tty_ioctl(struct inode * inode, struct file * file, 1152static long hung_up_tty_ioctl(struct file * file,
1147 unsigned int cmd, unsigned long arg) 1153 unsigned int cmd, unsigned long arg)
1148{ 1154{
1149 return cmd == TIOCSPGRP ? -ENOTTY : -EIO; 1155 return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
1150} 1156}
@@ -1155,6 +1161,7 @@ static const struct file_operations tty_fops = {
1155 .write = tty_write, 1161 .write = tty_write,
1156 .poll = tty_poll, 1162 .poll = tty_poll,
1157 .ioctl = tty_ioctl, 1163 .ioctl = tty_ioctl,
1164 .compat_ioctl = tty_compat_ioctl,
1158 .open = tty_open, 1165 .open = tty_open,
1159 .release = tty_release, 1166 .release = tty_release,
1160 .fasync = tty_fasync, 1167 .fasync = tty_fasync,
@@ -1167,6 +1174,7 @@ static const struct file_operations ptmx_fops = {
1167 .write = tty_write, 1174 .write = tty_write,
1168 .poll = tty_poll, 1175 .poll = tty_poll,
1169 .ioctl = tty_ioctl, 1176 .ioctl = tty_ioctl,
1177 .compat_ioctl = tty_compat_ioctl,
1170 .open = ptmx_open, 1178 .open = ptmx_open,
1171 .release = tty_release, 1179 .release = tty_release,
1172 .fasync = tty_fasync, 1180 .fasync = tty_fasync,
@@ -1179,6 +1187,7 @@ static const struct file_operations console_fops = {
1179 .write = redirected_tty_write, 1187 .write = redirected_tty_write,
1180 .poll = tty_poll, 1188 .poll = tty_poll,
1181 .ioctl = tty_ioctl, 1189 .ioctl = tty_ioctl,
1190 .compat_ioctl = tty_compat_ioctl,
1182 .open = tty_open, 1191 .open = tty_open,
1183 .release = tty_release, 1192 .release = tty_release,
1184 .fasync = tty_fasync, 1193 .fasync = tty_fasync,
@@ -1189,7 +1198,8 @@ static const struct file_operations hung_up_tty_fops = {
1189 .read = hung_up_tty_read, 1198 .read = hung_up_tty_read,
1190 .write = hung_up_tty_write, 1199 .write = hung_up_tty_write,
1191 .poll = hung_up_tty_poll, 1200 .poll = hung_up_tty_poll,
1192 .ioctl = hung_up_tty_ioctl, 1201 .unlocked_ioctl = hung_up_tty_ioctl,
1202 .compat_ioctl = hung_up_tty_ioctl,
1193 .release = tty_release, 1203 .release = tty_release,
1194}; 1204};
1195 1205
@@ -3357,6 +3367,32 @@ int tty_ioctl(struct inode * inode, struct file * file,
3357 return retval; 3367 return retval;
3358} 3368}
3359 3369
3370#ifdef CONFIG_COMPAT
3371static long tty_compat_ioctl(struct file * file, unsigned int cmd,
3372 unsigned long arg)
3373{
3374 struct inode *inode = file->f_dentry->d_inode;
3375 struct tty_struct *tty = file->private_data;
3376 struct tty_ldisc *ld;
3377 int retval = -ENOIOCTLCMD;
3378
3379 if (tty_paranoia_check(tty, inode, "tty_ioctl"))
3380 return -EINVAL;
3381
3382 if (tty->driver->compat_ioctl) {
3383 retval = (tty->driver->compat_ioctl)(tty, file, cmd, arg);
3384 if (retval != -ENOIOCTLCMD)
3385 return retval;
3386 }
3387
3388 ld = tty_ldisc_ref_wait(tty);
3389 if (ld->compat_ioctl)
3390 retval = ld->compat_ioctl(tty, file, cmd, arg);
3391 tty_ldisc_deref(ld);
3392
3393 return retval;
3394}
3395#endif
3360 3396
3361/* 3397/*
3362 * This implements the "Secure Attention Key" --- the idea is to 3398 * This implements the "Secure Attention Key" --- the idea is to
@@ -3689,6 +3725,7 @@ void tty_set_operations(struct tty_driver *driver,
3689 driver->write_room = op->write_room; 3725 driver->write_room = op->write_room;
3690 driver->chars_in_buffer = op->chars_in_buffer; 3726 driver->chars_in_buffer = op->chars_in_buffer;
3691 driver->ioctl = op->ioctl; 3727 driver->ioctl = op->ioctl;
3728 driver->compat_ioctl = op->compat_ioctl;
3692 driver->set_termios = op->set_termios; 3729 driver->set_termios = op->set_termios;
3693 driver->throttle = op->throttle; 3730 driver->throttle = op->throttle;
3694 driver->unthrottle = op->unthrottle; 3731 driver->unthrottle = op->unthrottle;
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index 659487e3ebeb..85c95cd39bc3 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -52,6 +52,11 @@
52 * This routine allows the tty driver to implement 52 * This routine allows the tty driver to implement
53 * device-specific ioctl's. If the ioctl number passed in cmd 53 * device-specific ioctl's. If the ioctl number passed in cmd
54 * is not recognized by the driver, it should return ENOIOCTLCMD. 54 * is not recognized by the driver, it should return ENOIOCTLCMD.
55 *
56 * long (*compat_ioctl)(struct tty_struct *tty, struct file * file,
57 * unsigned int cmd, unsigned long arg);
58 *
59 * implement ioctl processing for 32 bit process on 64 bit system
55 * 60 *
56 * void (*set_termios)(struct tty_struct *tty, struct ktermios * old); 61 * void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
57 * 62 *
@@ -132,6 +137,8 @@ struct tty_operations {
132 int (*chars_in_buffer)(struct tty_struct *tty); 137 int (*chars_in_buffer)(struct tty_struct *tty);
133 int (*ioctl)(struct tty_struct *tty, struct file * file, 138 int (*ioctl)(struct tty_struct *tty, struct file * file,
134 unsigned int cmd, unsigned long arg); 139 unsigned int cmd, unsigned long arg);
140 long (*compat_ioctl)(struct tty_struct *tty, struct file * file,
141 unsigned int cmd, unsigned long arg);
135 void (*set_termios)(struct tty_struct *tty, struct ktermios * old); 142 void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
136 void (*throttle)(struct tty_struct * tty); 143 void (*throttle)(struct tty_struct * tty);
137 void (*unthrottle)(struct tty_struct * tty); 144 void (*unthrottle)(struct tty_struct * tty);
@@ -193,6 +200,8 @@ struct tty_driver {
193 int (*chars_in_buffer)(struct tty_struct *tty); 200 int (*chars_in_buffer)(struct tty_struct *tty);
194 int (*ioctl)(struct tty_struct *tty, struct file * file, 201 int (*ioctl)(struct tty_struct *tty, struct file * file,
195 unsigned int cmd, unsigned long arg); 202 unsigned int cmd, unsigned long arg);
203 long (*compat_ioctl)(struct tty_struct *tty, struct file * file,
204 unsigned int cmd, unsigned long arg);
196 void (*set_termios)(struct tty_struct *tty, struct ktermios * old); 205 void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
197 void (*throttle)(struct tty_struct * tty); 206 void (*throttle)(struct tty_struct * tty);
198 void (*unthrottle)(struct tty_struct * tty); 207 void (*unthrottle)(struct tty_struct * tty);
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h
index d75932e27710..6226504d9108 100644
--- a/include/linux/tty_ldisc.h
+++ b/include/linux/tty_ldisc.h
@@ -59,6 +59,11 @@
59 * low-level driver can "grab" an ioctl request before the line 59 * low-level driver can "grab" an ioctl request before the line
60 * discpline has a chance to see it. 60 * discpline has a chance to see it.
61 * 61 *
62 * long (*compat_ioctl)(struct tty_struct * tty, struct file * file,
63 * unsigned int cmd, unsigned long arg);
64 *
65 * Process ioctl calls from 32-bit process on 64-bit system
66 *
62 * void (*set_termios)(struct tty_struct *tty, struct ktermios * old); 67 * void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
63 * 68 *
64 * This function notifies the line discpline that a change has 69 * This function notifies the line discpline that a change has
@@ -118,6 +123,8 @@ struct tty_ldisc {
118 const unsigned char * buf, size_t nr); 123 const unsigned char * buf, size_t nr);
119 int (*ioctl)(struct tty_struct * tty, struct file * file, 124 int (*ioctl)(struct tty_struct * tty, struct file * file,
120 unsigned int cmd, unsigned long arg); 125 unsigned int cmd, unsigned long arg);
126 long (*compat_ioctl)(struct tty_struct * tty, struct file * file,
127 unsigned int cmd, unsigned long arg);
121 void (*set_termios)(struct tty_struct *tty, struct ktermios * old); 128 void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
122 unsigned int (*poll)(struct tty_struct *, struct file *, 129 unsigned int (*poll)(struct tty_struct *, struct file *,
123 struct poll_table_struct *); 130 struct poll_table_struct *);