diff options
| -rw-r--r-- | drivers/char/n_tty.c | 29 | ||||
| -rw-r--r-- | drivers/char/tty_io.c | 43 | ||||
| -rw-r--r-- | include/linux/tty_driver.h | 9 | ||||
| -rw-r--r-- | include/linux/tty_ldisc.h | 7 |
4 files changed, 69 insertions, 19 deletions
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index 6ac3ca4c72..b3d4ccc33a 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 | ||
| 1546 | struct tty_ldisc tty_ldisc_N_TTY = { | 1546 | struct 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 fc662e4ce5..fe62c2170d 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 *); | |||
| 151 | static int tty_release(struct inode *, struct file *); | 151 | static int tty_release(struct inode *, struct file *); |
| 152 | int tty_ioctl(struct inode * inode, struct file * file, | 152 | int 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 | ||
| 155 | static long tty_compat_ioctl(struct file * file, unsigned int cmd, | ||
| 156 | unsigned long arg); | ||
| 157 | #else | ||
| 158 | #define tty_compat_ioctl NULL | ||
| 159 | #endif | ||
| 154 | static int tty_fasync(int fd, struct file * filp, int on); | 160 | static int tty_fasync(int fd, struct file * filp, int on); |
| 155 | static void release_tty(struct tty_struct *tty, int idx); | 161 | static void release_tty(struct tty_struct *tty, int idx); |
| 156 | static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); | 162 | static 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 | ||
| 1146 | static int hung_up_tty_ioctl(struct inode * inode, struct file * file, | 1152 | static 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 | ||
| 3371 | static 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 659487e3eb..85c95cd39b 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 d75932e277..6226504d91 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 *); |
