From 77021f8bab02d8099c7ae4360aa6746b3b733ba7 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 16:02:34 -0400 Subject: [PATCH 01/53] presence of RS485 ioctls has been unconditional since 2014 Signed-off-by: Al Viro --- fs/compat_ioctl.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index a9b00942e87d7..53bc3659dcef5 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -749,12 +749,8 @@ COMPATIBLE_IOCTL(TIOCOUTQ) COMPATIBLE_IOCTL(TIOCSPGRP) COMPATIBLE_IOCTL(TIOCGPGRP) COMPATIBLE_IOCTL(TIOCSERGETLSR) -#ifdef TIOCSRS485 COMPATIBLE_IOCTL(TIOCSRS485) -#endif -#ifdef TIOCGRS485 COMPATIBLE_IOCTL(TIOCGRS485) -#endif #ifdef TCGETS2 COMPATIBLE_IOCTL(TCGETS2) COMPATIBLE_IOCTL(TCSETS2) From e21120383f2dce32312f63ffca145ff8a87d41f5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 19:47:09 -0400 Subject: [PATCH 02/53] move compat handling of tty ioctls to tty_compat_ioctl() ioctls that are * callable only via tty_ioctl() * not driver-specific * not demand data structure conversions * either always need passing arg as is or always demand compat_ptr() get intercepted in tty_compat_ioctl() from the very beginning and redirecter to tty_ioctl(). As the result, their entries in fs/compat_ioctl.c (some of those had been missing, BTW) got removed, as well as n_tty_compat_ioctl_helper() (now it's never called with any cmd it would accept). Signed-off-by: Al Viro --- drivers/tty/tty_io.c | 78 +++++++++++++++++++++++++++++++++++++++-- drivers/tty/tty_ioctl.c | 16 --------- fs/compat_ioctl.c | 51 --------------------------- include/linux/tty.h | 2 -- 4 files changed, 76 insertions(+), 71 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 32bc3e3fe4d30..7bfc8afc130a6 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -97,6 +97,7 @@ #include #include #include +#include #include @@ -2668,6 +2669,81 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, struct tty_ldisc *ld; int retval = -ENOIOCTLCMD; + switch (cmd) { + case TIOCSTI: + case TIOCGWINSZ: + case TIOCSWINSZ: + case TIOCGEXCL: + case TIOCGETD: + case TIOCSETD: + case TIOCGDEV: + case TIOCMGET: + case TIOCMSET: + case TIOCMBIC: + case TIOCMBIS: + case TIOCGICOUNT: + case TIOCGPGRP: + case TIOCSPGRP: + case TIOCGSID: + case TIOCSERGETLSR: + case TIOCGRS485: + case TIOCSRS485: +#ifdef TIOCGETP + case TIOCGETP: + case TIOCSETP: + case TIOCSETN: +#endif +#ifdef TIOCGETC + case TIOCGETC: + case TIOCSETC: +#endif +#ifdef TIOCGLTC + case TIOCGLTC: + case TIOCSLTC: +#endif + case TCSETSF: + case TCSETSW: + case TCSETS: + case TCGETS: +#ifdef TCGETS2 + case TCGETS2: + case TCSETSF2: + case TCSETSW2: + case TCSETS2: +#endif + case TCGETA: + case TCSETAF: + case TCSETAW: + case TCSETA: + case TIOCGLCKTRMIOS: + case TIOCSLCKTRMIOS: +#ifdef TCGETX + case TCGETX: + case TCSETX: + case TCSETXW: + case TCSETXF: +#endif + case TIOCGSOFTCAR: + case TIOCSSOFTCAR: + return tty_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); + case TIOCCONS: + case TIOCEXCL: + case TIOCNXCL: + case TIOCVHANGUP: + case TIOCSBRK: + case TIOCCBRK: + case TCSBRK: + case TCSBRKP: + case TCFLSH: + case TIOCGPTPEER: + case TIOCNOTTY: + case TIOCSCTTY: + case TCXONC: + case TIOCMIWAIT: + case TIOCSERCONFIG: + return tty_ioctl(file, cmd, arg); + } + if (tty_paranoia_check(tty, file_inode(file), "tty_ioctl")) return -EINVAL; @@ -2682,8 +2758,6 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, return hung_up_tty_compat_ioctl(file, cmd, arg); if (ld->ops->compat_ioctl) retval = ld->ops->compat_ioctl(tty, file, cmd, arg); - else - retval = n_tty_compat_ioctl_helper(tty, file, cmd, arg); tty_ldisc_deref(ld); return retval; diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index d99fec44036c3..9245fffdbceb1 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -941,19 +941,3 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, } } EXPORT_SYMBOL(n_tty_ioctl_helper); - -#ifdef CONFIG_COMPAT -long n_tty_compat_ioctl_helper(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - case TIOCGLCKTRMIOS: - case TIOCSLCKTRMIOS: - return tty_mode_ioctl(tty, file, cmd, (unsigned long) compat_ptr(arg)); - default: - return -ENOIOCTLCMD; - } -} -EXPORT_SYMBOL(n_tty_compat_ioctl_helper); -#endif - diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 53bc3659dcef5..670b8cbd08966 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -711,52 +711,9 @@ COMPATIBLE_IOCTL(0x4B50) /* KDGHWCLK - not in the kernel, but don't complain * COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain */ /* Big T */ -COMPATIBLE_IOCTL(TCGETA) -COMPATIBLE_IOCTL(TCSETA) -COMPATIBLE_IOCTL(TCSETAW) -COMPATIBLE_IOCTL(TCSETAF) -COMPATIBLE_IOCTL(TCSBRK) -COMPATIBLE_IOCTL(TCXONC) -COMPATIBLE_IOCTL(TCFLSH) -COMPATIBLE_IOCTL(TCGETS) -COMPATIBLE_IOCTL(TCSETS) -COMPATIBLE_IOCTL(TCSETSW) -COMPATIBLE_IOCTL(TCSETSF) COMPATIBLE_IOCTL(TIOCLINUX) -COMPATIBLE_IOCTL(TIOCSBRK) -COMPATIBLE_IOCTL(TIOCGDEV) -COMPATIBLE_IOCTL(TIOCCBRK) -COMPATIBLE_IOCTL(TIOCGSID) -COMPATIBLE_IOCTL(TIOCGICOUNT) -COMPATIBLE_IOCTL(TIOCGEXCL) /* Little t */ -COMPATIBLE_IOCTL(TIOCGETD) -COMPATIBLE_IOCTL(TIOCSETD) -COMPATIBLE_IOCTL(TIOCEXCL) -COMPATIBLE_IOCTL(TIOCNXCL) -COMPATIBLE_IOCTL(TIOCCONS) -COMPATIBLE_IOCTL(TIOCGSOFTCAR) -COMPATIBLE_IOCTL(TIOCSSOFTCAR) -COMPATIBLE_IOCTL(TIOCSWINSZ) -COMPATIBLE_IOCTL(TIOCGWINSZ) -COMPATIBLE_IOCTL(TIOCMGET) -COMPATIBLE_IOCTL(TIOCMBIC) -COMPATIBLE_IOCTL(TIOCMBIS) -COMPATIBLE_IOCTL(TIOCMSET) -COMPATIBLE_IOCTL(TIOCNOTTY) -COMPATIBLE_IOCTL(TIOCSTI) COMPATIBLE_IOCTL(TIOCOUTQ) -COMPATIBLE_IOCTL(TIOCSPGRP) -COMPATIBLE_IOCTL(TIOCGPGRP) -COMPATIBLE_IOCTL(TIOCSERGETLSR) -COMPATIBLE_IOCTL(TIOCSRS485) -COMPATIBLE_IOCTL(TIOCGRS485) -#ifdef TCGETS2 -COMPATIBLE_IOCTL(TCGETS2) -COMPATIBLE_IOCTL(TCSETS2) -COMPATIBLE_IOCTL(TCSETSW2) -COMPATIBLE_IOCTL(TCSETSF2) -#endif /* Little f */ COMPATIBLE_IOCTL(FIOCLEX) COMPATIBLE_IOCTL(FIONCLEX) @@ -1219,10 +1176,6 @@ COMPATIBLE_IOCTL(JSIOCGAXES) COMPATIBLE_IOCTL(JSIOCGBUTTONS) COMPATIBLE_IOCTL(JSIOCGNAME(0)) -#ifdef TIOCGLTC -COMPATIBLE_IOCTL(TIOCGLTC) -COMPATIBLE_IOCTL(TIOCSLTC) -#endif #ifdef TIOCSTART /* * For these two we have definitions in ioctls.h and/or termios.h on @@ -1312,10 +1265,6 @@ static long do_ioctl_trans(unsigned int cmd, * so we must not do a compat_ptr() translation. */ switch (cmd) { - /* Big T */ - case TCSBRKP: - case TIOCMIWAIT: - case TIOCSCTTY: /* RAID */ case HOT_REMOVE_DISK: case HOT_ADD_DISK: diff --git a/include/linux/tty.h b/include/linux/tty.h index c56e3978b00f5..414db2bce7150 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -746,8 +746,6 @@ static inline int tty_audit_push(void) /* tty_ioctl.c */ extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); -extern long n_tty_compat_ioctl_helper(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg); /* vt.c */ From a913bc76ed7bdc0b31255268afcb7feffdc8600b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 19:52:54 -0400 Subject: [PATCH 03/53] tty_ioctl(): drop FIONBIO handling That code had been live for 11 weeks back in 1992, but it had been 26 years since sys_ioctl() began handling FIONBIO on its own. Time to to bury the body, already... Signed-off-by: Al Viro --- drivers/tty/tty_io.c | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 7bfc8afc130a6..ef2a8766d34f2 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2288,34 +2288,6 @@ static int tioccons(struct file *file) return 0; } -/** - * fionbio - non blocking ioctl - * @file: file to set blocking value - * @p: user parameter - * - * Historical tty interfaces had a blocking control ioctl before - * the generic functionality existed. This piece of history is preserved - * in the expected tty API of posix OS's. - * - * Locking: none, the open file handle ensures it won't go away. - */ - -static int fionbio(struct file *file, int __user *p) -{ - int nonblock; - - if (get_user(nonblock, p)) - return -EFAULT; - - spin_lock(&file->f_lock); - if (nonblock) - file->f_flags |= O_NONBLOCK; - else - file->f_flags &= ~O_NONBLOCK; - spin_unlock(&file->f_lock); - return 0; -} - /** * tiocsetd - set line discipline * @tty: tty device @@ -2562,8 +2534,6 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return tiocswinsz(real_tty, p); case TIOCCONS: return real_tty != tty ? -EINVAL : tioccons(file); - case FIONBIO: - return fionbio(file, p); case TIOCEXCL: set_bit(TTY_EXCLUSIVE, &tty->flags); return 0; From 7eaec37e04616136915ad2207417beb29445fc35 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 00:13:10 -0400 Subject: [PATCH 04/53] mos7720: bury dead TIOCM... in ->ioctl() These ioctls never reach driver's ->ioctl() - tty_ioctl() handles them on its own. ->tiocm[gs]et() is what actually gets called, and mos7720 provides those, with results equivalent to what the unreachable code would be doing when called. Signed-off-by: Al Viro --- drivers/usb/serial/mos7720.c | 52 ------------------------------------ 1 file changed, 52 deletions(-) diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 27109522fd8b2..4c06357b3ef8d 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -1786,51 +1786,6 @@ static int mos7720_tiocmset(struct tty_struct *tty, return 0; } -static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd, - unsigned int __user *value) -{ - unsigned int mcr; - unsigned int arg; - - struct usb_serial_port *port; - - if (mos7720_port == NULL) - return -1; - - port = (struct usb_serial_port *)mos7720_port->port; - mcr = mos7720_port->shadowMCR; - - if (copy_from_user(&arg, value, sizeof(int))) - return -EFAULT; - - switch (cmd) { - case TIOCMBIS: - if (arg & TIOCM_RTS) - mcr |= UART_MCR_RTS; - if (arg & TIOCM_DTR) - mcr |= UART_MCR_RTS; - if (arg & TIOCM_LOOP) - mcr |= UART_MCR_LOOP; - break; - - case TIOCMBIC: - if (arg & TIOCM_RTS) - mcr &= ~UART_MCR_RTS; - if (arg & TIOCM_DTR) - mcr &= ~UART_MCR_RTS; - if (arg & TIOCM_LOOP) - mcr &= ~UART_MCR_LOOP; - break; - - } - - mos7720_port->shadowMCR = mcr; - write_mos_reg(port->serial, port->port_number, MOS7720_MCR, - mos7720_port->shadowMCR); - - return 0; -} - static int get_serial_info(struct moschip_port *mos7720_port, struct serial_struct __user *retinfo) { @@ -1868,13 +1823,6 @@ static int mos7720_ioctl(struct tty_struct *tty, return get_lsr_info(tty, mos7720_port, (unsigned int __user *)arg); - /* FIXME: These should be using the mode methods */ - case TIOCMBIS: - case TIOCMBIC: - dev_dbg(&port->dev, "%s TIOCMSET/TIOCMBIC/TIOCMSET\n", __func__); - return set_modem_info(mos7720_port, cmd, - (unsigned int __user *)arg); - case TIOCGSERIAL: dev_dbg(&port->dev, "%s TIOCGSERIAL\n", __func__); return get_serial_info(mos7720_port, From 2f46a2c1d4eb982b82c199e1bd5cddab12681275 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 21:53:32 -0400 Subject: [PATCH 05/53] tty_ioctl(): start taking TIOC[SG]SERIAL into separate methods ->set_serial() and ->get_serial() resp., both taking tty and a kernel pointer to serial_struct. Signed-off-by: Al Viro --- drivers/tty/tty_io.c | 35 ++++++++++++++++++++++++++++++----- include/linux/tty_driver.h | 3 +++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index ef2a8766d34f2..b96bfd051d590 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2456,22 +2456,40 @@ static int tty_tiocgicount(struct tty_struct *tty, void __user *arg) return 0; } -static void tty_warn_deprecated_flags(struct serial_struct __user *ss) +static int tty_tiocsserial(struct tty_struct *tty, struct serial_struct __user *ss) { static DEFINE_RATELIMIT_STATE(depr_flags, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); char comm[TASK_COMM_LEN]; + struct serial_struct v; int flags; - if (get_user(flags, &ss->flags)) - return; + if (copy_from_user(&v, ss, sizeof(struct serial_struct))) + return -EFAULT; - flags &= ASYNC_DEPRECATED; + flags = v.flags & ASYNC_DEPRECATED; if (flags && __ratelimit(&depr_flags)) pr_warn("%s: '%s' is using deprecated serial flags (with no effect): %.8x\n", __func__, get_task_comm(comm, current), flags); + if (!tty->ops->set_serial) + return -ENOIOCTLCMD; + return tty->ops->set_serial(tty, &v); +} + +static int tty_tiocgserial(struct tty_struct *tty, struct serial_struct __user *ss) +{ + struct serial_struct v; + int err; + + memset(&v, 0, sizeof(struct serial_struct)); + if (!tty->ops->get_serial) + return -ENOIOCTLCMD; + err = tty->ops->get_serial(tty, &v); + if (!err && copy_to_user(ss, &v, sizeof(struct serial_struct))) + err = -EFAULT; + return err; } /* @@ -2603,7 +2621,14 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } break; case TIOCSSERIAL: - tty_warn_deprecated_flags(p); + retval = tty_tiocsserial(tty, p); + if (retval != -ENOIOCTLCMD) + return retval; + break; + case TIOCGSERIAL: + retval = tty_tiocgserial(tty, p); + if (retval != -ENOIOCTLCMD) + return retval; break; case TIOCGPTPEER: /* Special because the struct file is needed */ diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 71dbc891851a4..358446247ccdc 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -249,6 +249,7 @@ struct tty_struct; struct tty_driver; struct serial_icounter_struct; +struct serial_struct; struct tty_operations { struct tty_struct * (*lookup)(struct tty_driver *driver, @@ -287,6 +288,8 @@ struct tty_operations { int (*set_termiox)(struct tty_struct *tty, struct termiox *tnew); int (*get_icount)(struct tty_struct *tty, struct serial_icounter_struct *icount); + int (*get_serial)(struct tty_struct *tty, struct serial_struct *p); + int (*set_serial)(struct tty_struct *tty, struct serial_struct *p); void (*show_fdinfo)(struct tty_struct *tty, struct seq_file *m); #ifdef CONFIG_CONSOLE_POLL int (*poll_init)(struct tty_driver *driver, int line, char *options); From 617a281104bd37ad88c2758f92e9be84cac5d123 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 21:56:47 -0400 Subject: [PATCH 06/53] simserial: switch to ->[sg]et_serial() Signed-off-by: Al Viro --- arch/ia64/hp/sim/simserial.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index 663388a73d4ec..de5e69162ad53 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -297,18 +297,25 @@ static void rs_unthrottle(struct tty_struct * tty) printk(KERN_INFO "simrs_unthrottle called\n"); } +static int rs_setserial(struct tty_struct *tty, struct serial_struct *ss) +{ + return 0; +} + +static int rs_getserial(struct tty_struct *tty, struct serial_struct *ss) +{ + return 0; +} + static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && + if ((cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && (cmd != TIOCMIWAIT)) { if (tty_io_error(tty)) return -EIO; } switch (cmd) { - case TIOCGSERIAL: - case TIOCSSERIAL: case TIOCSERGSTRUCT: case TIOCMIWAIT: return 0; @@ -448,6 +455,8 @@ static const struct tty_operations hp_ops = { .throttle = rs_throttle, .unthrottle = rs_unthrottle, .send_xchar = rs_send_xchar, + .set_serial = rs_setserial, + .get_serial = rs_getserial, .hangup = rs_hangup, .proc_show = rs_proc_show, }; From b98e5a6791473e0bdb71df5d1db48f156e2dee79 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 21:58:08 -0400 Subject: [PATCH 07/53] fwserial: switch to ->[sg]et_serial() Signed-off-by: Al Viro --- drivers/staging/fwserial/fwserial.c | 66 ++++++++++++----------------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index fa0dd425b4549..173f451b86b71 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -1209,42 +1209,40 @@ static int wait_msr_change(struct fwtty_port *port, unsigned long mask) check_msr_delta(port, mask, &prev)); } -static int get_serial_info(struct fwtty_port *port, - struct serial_struct __user *info) +static int get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct tmp; - - memset(&tmp, 0, sizeof(tmp)); - - tmp.type = PORT_UNKNOWN; - tmp.line = port->port.tty->index; - tmp.flags = port->port.flags; - tmp.xmit_fifo_size = FWTTY_PORT_TXFIFO_LEN; - tmp.baud_base = 400000000; - tmp.close_delay = port->port.close_delay; - - return (copy_to_user(info, &tmp, sizeof(*info))) ? -EFAULT : 0; + struct fwtty_port *port = tty->driver_data; + mutex_lock(&port->port.mutex); + ss->type = PORT_UNKNOWN; + ss->line = port->port.tty->index; + ss->flags = port->port.flags; + ss->xmit_fifo_size = FWTTY_PORT_TXFIFO_LEN; + ss->baud_base = 400000000; + ss->close_delay = port->port.close_delay; + mutex_unlock(&port->port.mutex); + return 0; } -static int set_serial_info(struct fwtty_port *port, - struct serial_struct __user *info) +static int set_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct tmp; - - if (copy_from_user(&tmp, info, sizeof(tmp))) - return -EFAULT; + struct fwtty_port *port = tty->driver_data; - if (tmp.irq != 0 || tmp.port != 0 || tmp.custom_divisor != 0 || - tmp.baud_base != 400000000) + if (ss->irq != 0 || ss->port != 0 || ss->custom_divisor != 0 || + ss->baud_base != 400000000) return -EPERM; + mutex_lock(&port->port.mutex); if (!capable(CAP_SYS_ADMIN)) { - if (((tmp.flags & ~ASYNC_USR_MASK) != - (port->port.flags & ~ASYNC_USR_MASK))) + if (((ss->flags & ~ASYNC_USR_MASK) != + (port->port.flags & ~ASYNC_USR_MASK))) { + mutex_unlock(&port->port.mutex); return -EPERM; - } else { - port->port.close_delay = tmp.close_delay * HZ / 100; + } } + port->port.close_delay = ss->close_delay * HZ / 100; + mutex_unlock(&port->port.mutex); return 0; } @@ -1256,18 +1254,6 @@ static int fwtty_ioctl(struct tty_struct *tty, unsigned int cmd, int err; switch (cmd) { - case TIOCGSERIAL: - mutex_lock(&port->port.mutex); - err = get_serial_info(port, (void __user *)arg); - mutex_unlock(&port->port.mutex); - break; - - case TIOCSSERIAL: - mutex_lock(&port->port.mutex); - err = set_serial_info(port, (void __user *)arg); - mutex_unlock(&port->port.mutex); - break; - case TIOCMIWAIT: err = wait_msr_change(port, arg); break; @@ -1557,6 +1543,8 @@ static const struct tty_operations fwtty_ops = { .tiocmget = fwtty_tiocmget, .tiocmset = fwtty_tiocmset, .get_icount = fwtty_get_icount, + .set_serial = set_serial_info, + .get_serial = get_serial_info, .proc_show = fwtty_proc_show, }; @@ -1578,6 +1566,8 @@ static const struct tty_operations fwloop_ops = { .tiocmget = fwtty_tiocmget, .tiocmset = fwtty_tiocmset, .get_icount = fwtty_get_icount, + .set_serial = set_serial_info, + .get_serial = get_serial_info, }; static inline int mgmt_pkt_expected_len(__be16 code) From 0aad5ad563c878fcb981cdbb52b4221bc0036e59 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 21:58:45 -0400 Subject: [PATCH 08/53] greybus/uart: switch to ->[sg]et_serial() Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/staging/greybus/uart.c | 47 +++++++++++++--------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index 8a006323c3c11..3313cb0b60af4 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -616,40 +616,33 @@ static void gb_tty_unthrottle(struct tty_struct *tty) } } -static int get_serial_info(struct gb_tty *gb_tty, - struct serial_struct __user *info) +static int get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct tmp; - - memset(&tmp, 0, sizeof(tmp)); - tmp.type = PORT_16550A; - tmp.line = gb_tty->minor; - tmp.xmit_fifo_size = 16; - tmp.baud_base = 9600; - tmp.close_delay = gb_tty->port.close_delay / 10; - tmp.closing_wait = + struct gb_tty *gb_tty = tty->driver_data; + + ss->type = PORT_16550A; + ss->line = gb_tty->minor; + ss->xmit_fifo_size = 16; + ss->baud_base = 9600; + ss->close_delay = gb_tty->port.close_delay / 10; + ss->closing_wait = gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? ASYNC_CLOSING_WAIT_NONE : gb_tty->port.closing_wait / 10; - - if (copy_to_user(info, &tmp, sizeof(tmp))) - return -EFAULT; return 0; } -static int set_serial_info(struct gb_tty *gb_tty, - struct serial_struct __user *newinfo) +static int set_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct new_serial; + struct gb_tty *gb_tty = tty->driver_data; unsigned int closing_wait; unsigned int close_delay; int retval = 0; - if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) - return -EFAULT; - - close_delay = new_serial.close_delay * 10; - closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? - ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10; + close_delay = ss->close_delay * 10; + closing_wait = ss->closing_wait == ASYNC_CLOSING_WAIT_NONE ? + ASYNC_CLOSING_WAIT_NONE : ss->closing_wait * 10; mutex_lock(&gb_tty->port.mutex); if (!capable(CAP_SYS_ADMIN)) { @@ -728,12 +721,6 @@ static int gb_tty_ioctl(struct tty_struct *tty, unsigned int cmd, struct gb_tty *gb_tty = tty->driver_data; switch (cmd) { - case TIOCGSERIAL: - return get_serial_info(gb_tty, - (struct serial_struct __user *)arg); - case TIOCSSERIAL: - return set_serial_info(gb_tty, - (struct serial_struct __user *)arg); case TIOCMIWAIT: return wait_serial_change(gb_tty, arg); } @@ -818,6 +805,8 @@ static const struct tty_operations gb_ops = { .tiocmget = gb_tty_tiocmget, .tiocmset = gb_tty_tiocmset, .get_icount = gb_tty_get_icount, + .set_serial = set_serial_info, + .get_serial = get_serial_info, }; static const struct tty_port_operations gb_port_ops = { From b129cbc99b2d09a4c4c5de60f91118ecb380e2fa Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 21:59:13 -0400 Subject: [PATCH 09/53] amiserial: switch to ->[sg]et_serial() Signed-off-by: Al Viro --- drivers/tty/amiserial.c | 78 +++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 45 deletions(-) diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 34dead6141498..51cfe4f1afcfd 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -996,63 +996,55 @@ static void rs_unthrottle(struct tty_struct * tty) * ------------------------------------------------------------ */ -static int get_serial_info(struct tty_struct *tty, struct serial_state *state, - struct serial_struct __user * retinfo) +static int get_serial_info(struct tty_struct *tty, struct serial_struct *ss) { - struct serial_struct tmp; - - memset(&tmp, 0, sizeof(tmp)); + struct serial_state *state = tty->driver_data; + tty_lock(tty); - tmp.line = tty->index; - tmp.port = state->port; - tmp.flags = state->tport.flags; - tmp.xmit_fifo_size = state->xmit_fifo_size; - tmp.baud_base = state->baud_base; - tmp.close_delay = state->tport.close_delay; - tmp.closing_wait = state->tport.closing_wait; - tmp.custom_divisor = state->custom_divisor; + ss->line = tty->index; + ss->port = state->port; + ss->flags = state->tport.flags; + ss->xmit_fifo_size = state->xmit_fifo_size; + ss->baud_base = state->baud_base; + ss->close_delay = state->tport.close_delay; + ss->closing_wait = state->tport.closing_wait; + ss->custom_divisor = state->custom_divisor; tty_unlock(tty); - if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) - return -EFAULT; return 0; } -static int set_serial_info(struct tty_struct *tty, struct serial_state *state, - struct serial_struct __user * new_info) +static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss) { + struct serial_state *state = tty->driver_data; struct tty_port *port = &state->tport; - struct serial_struct new_serial; bool change_spd; int retval = 0; - if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) - return -EFAULT; - tty_lock(tty); - change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) || - new_serial.custom_divisor != state->custom_divisor; - if (new_serial.irq || new_serial.port != state->port || - new_serial.xmit_fifo_size != state->xmit_fifo_size) { + change_spd = ((ss->flags ^ port->flags) & ASYNC_SPD_MASK) || + ss->custom_divisor != state->custom_divisor; + if (ss->irq || ss->port != state->port || + ss->xmit_fifo_size != state->xmit_fifo_size) { tty_unlock(tty); return -EINVAL; } if (!serial_isroot()) { - if ((new_serial.baud_base != state->baud_base) || - (new_serial.close_delay != port->close_delay) || - (new_serial.xmit_fifo_size != state->xmit_fifo_size) || - ((new_serial.flags & ~ASYNC_USR_MASK) != + if ((ss->baud_base != state->baud_base) || + (ss->close_delay != port->close_delay) || + (ss->xmit_fifo_size != state->xmit_fifo_size) || + ((ss->flags & ~ASYNC_USR_MASK) != (port->flags & ~ASYNC_USR_MASK))) { tty_unlock(tty); return -EPERM; } port->flags = ((port->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - state->custom_divisor = new_serial.custom_divisor; + (ss->flags & ASYNC_USR_MASK)); + state->custom_divisor = ss->custom_divisor; goto check_and_exit; } - if (new_serial.baud_base < 9600) { + if (ss->baud_base < 9600) { tty_unlock(tty); return -EINVAL; } @@ -1062,19 +1054,19 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, * At this point, we start making changes..... */ - state->baud_base = new_serial.baud_base; + state->baud_base = ss->baud_base; port->flags = ((port->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - state->custom_divisor = new_serial.custom_divisor; - port->close_delay = new_serial.close_delay * HZ/100; - port->closing_wait = new_serial.closing_wait * HZ/100; + (ss->flags & ASYNC_FLAGS)); + state->custom_divisor = ss->custom_divisor; + port->close_delay = ss->close_delay * HZ/100; + port->closing_wait = ss->closing_wait * HZ/100; port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; check_and_exit: if (tty_port_initialized(port)) { if (change_spd) { /* warn about deprecation unless clearing */ - if (new_serial.flags & ASYNC_SPD_MASK) + if (ss->flags & ASYNC_SPD_MASK) dev_warn_ratelimited(tty->dev, "use of SPD flags is deprecated\n"); change_speed(tty, state, NULL); } @@ -1084,7 +1076,6 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, return retval; } - /* * get_lsr_info - get line status register info * @@ -1224,18 +1215,13 @@ static int rs_ioctl(struct tty_struct *tty, if (serial_paranoia_check(info, tty->name, "rs_ioctl")) return -ENODEV; - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && + if ((cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { if (tty_io_error(tty)) return -EIO; } switch (cmd) { - case TIOCGSERIAL: - return get_serial_info(tty, info, argp); - case TIOCSSERIAL: - return set_serial_info(tty, info, argp); case TIOCSERCONFIG: return 0; @@ -1607,6 +1593,8 @@ static const struct tty_operations serial_ops = { .tiocmget = rs_tiocmget, .tiocmset = rs_tiocmset, .get_icount = rs_get_icount, + .set_serial = set_serial_info, + .get_serial = get_serial_info, .proc_show = rs_proc_show, }; From 6fbf9582548105e7548a2342f67b32977fe8a43a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 21:59:48 -0400 Subject: [PATCH 10/53] cyclades: switch to ->[sg]et_serial() Signed-off-by: Al Viro --- drivers/tty/cyclades.c | 77 ++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index 6d3c58051ce33..4562c8060d09e 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c @@ -2257,44 +2257,45 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty) } } /* set_line_char */ -static int cy_get_serial_info(struct cyclades_port *info, - struct serial_struct __user *retinfo) +static int cy_get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { + struct cyclades_port *info = tty->driver_data; struct cyclades_card *cinfo = info->card; - struct serial_struct tmp = { - .type = info->type, - .line = info->line, - .port = (info->card - cy_card) * 0x100 + info->line - - cinfo->first_line, - .irq = cinfo->irq, - .flags = info->port.flags, - .close_delay = info->port.close_delay, - .closing_wait = info->port.closing_wait, - .baud_base = info->baud, - .custom_divisor = info->custom_divisor, - }; - return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; + + if (serial_paranoia_check(info, tty->name, "cy_ioctl")) + return -ENODEV; + ss->type = info->type; + ss->line = info->line; + ss->port = (info->card - cy_card) * 0x100 + info->line - + cinfo->first_line; + ss->irq = cinfo->irq; + ss->flags = info->port.flags; + ss->close_delay = info->port.close_delay; + ss->closing_wait = info->port.closing_wait; + ss->baud_base = info->baud; + ss->custom_divisor = info->custom_divisor; + return 0; } -static int -cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty, - struct serial_struct __user *new_info) +static int cy_set_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct new_serial; + struct cyclades_port *info = tty->driver_data; int old_flags; int ret; - if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) - return -EFAULT; + if (serial_paranoia_check(info, tty->name, "cy_ioctl")) + return -ENODEV; mutex_lock(&info->port.mutex); old_flags = info->port.flags; if (!capable(CAP_SYS_ADMIN)) { - if (new_serial.close_delay != info->port.close_delay || - new_serial.baud_base != info->baud || - (new_serial.flags & ASYNC_FLAGS & + if (ss->close_delay != info->port.close_delay || + ss->baud_base != info->baud || + (ss->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) != (info->port.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)) { @@ -2302,9 +2303,9 @@ cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty, return -EPERM; } info->port.flags = (info->port.flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK); - info->baud = new_serial.baud_base; - info->custom_divisor = new_serial.custom_divisor; + (ss->flags & ASYNC_USR_MASK); + info->baud = ss->baud_base; + info->custom_divisor = ss->custom_divisor; goto check_and_exit; } @@ -2313,18 +2314,18 @@ cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty, * At this point, we start making changes..... */ - info->baud = new_serial.baud_base; - info->custom_divisor = new_serial.custom_divisor; + info->baud = ss->baud_base; + info->custom_divisor = ss->custom_divisor; info->port.flags = (info->port.flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS); - info->port.close_delay = new_serial.close_delay * HZ / 100; - info->port.closing_wait = new_serial.closing_wait * HZ / 100; + (ss->flags & ASYNC_FLAGS); + info->port.close_delay = ss->close_delay * HZ / 100; + info->port.closing_wait = ss->closing_wait * HZ / 100; check_and_exit: if (tty_port_initialized(&info->port)) { - if ((new_serial.flags ^ old_flags) & ASYNC_SPD_MASK) { + if ((ss->flags ^ old_flags) & ASYNC_SPD_MASK) { /* warn about deprecation unless clearing */ - if (new_serial.flags & ASYNC_SPD_MASK) + if (ss->flags & ASYNC_SPD_MASK) dev_warn_ratelimited(tty->dev, "use of SPD flags is deprecated\n"); } cy_set_line_char(info, tty); @@ -2698,12 +2699,6 @@ cy_ioctl(struct tty_struct *tty, case CYGETWAIT: ret_val = info->port.closing_wait / (HZ / 100); break; - case TIOCGSERIAL: - ret_val = cy_get_serial_info(info, argp); - break; - case TIOCSSERIAL: - ret_val = cy_set_serial_info(info, tty, argp); - break; case TIOCSERGETLSR: /* Get line status register */ ret_val = get_lsr_info(info, argp); break; @@ -4011,6 +4006,8 @@ static const struct tty_operations cy_ops = { .tiocmget = cy_tiocmget, .tiocmset = cy_tiocmset, .get_icount = cy_get_icount, + .set_serial = cy_set_serial_info, + .get_serial = cy_get_serial_info, .proc_show = cyclades_proc_show, }; From a7b06fcf2ecef39b37979ac8b8838a182ba569e2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 22:00:08 -0400 Subject: [PATCH 11/53] ipwireless: switch to ->[sg]et_serial() Acked-by: David Sterba Signed-off-by: Al Viro --- drivers/tty/ipwireless/tty.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index 1ef751c27ac6d..fad3401e604d9 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c @@ -248,22 +248,29 @@ static int ipw_write_room(struct tty_struct *linux_tty) return room; } -static int ipwireless_get_serial_info(struct ipw_tty *tty, - struct serial_struct __user *retinfo) +static int ipwireless_get_serial_info(struct tty_struct *linux_tty, + struct serial_struct *ss) { - struct serial_struct tmp; + struct ipw_tty *tty = linux_tty->driver_data; - memset(&tmp, 0, sizeof(tmp)); - tmp.type = PORT_UNKNOWN; - tmp.line = tty->index; - tmp.baud_base = 115200; + if (!tty) + return -ENODEV; - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; + if (!tty->port.count) + return -EINVAL; + ss->type = PORT_UNKNOWN; + ss->line = tty->index; + ss->baud_base = 115200; return 0; } +static int ipwireless_set_serial_info(struct tty_struct *linux_tty, + struct serial_struct *ss) +{ + return 0; /* Keeps the PCMCIA scripts happy. */ +} + static int ipw_chars_in_buffer(struct tty_struct *linux_tty) { struct ipw_tty *tty = linux_tty->driver_data; @@ -386,15 +393,6 @@ static int ipw_ioctl(struct tty_struct *linux_tty, return -EINVAL; /* FIXME: Exactly how is the tty object locked here .. */ - - switch (cmd) { - case TIOCGSERIAL: - return ipwireless_get_serial_info(tty, (void __user *) arg); - - case TIOCSSERIAL: - return 0; /* Keeps the PCMCIA scripts happy. */ - } - if (tty->tty_type == TTYTYPE_MODEM) { switch (cmd) { case PPPIOCGCHAN: @@ -561,6 +559,8 @@ static const struct tty_operations tty_ops = { .chars_in_buffer = ipw_chars_in_buffer, .tiocmget = ipw_tiocmget, .tiocmset = ipw_tiocmset, + .set_serial = ipwireless_set_serial_info, + .get_serial = ipwireless_get_serial_info, }; int ipwireless_tty_init(void) From b60f38c6640f3b0e15f37c63167df9560fe00e6a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 22:00:37 -0400 Subject: [PATCH 12/53] isicom: switch to ->[sg]et_serial() Signed-off-by: Al Viro --- drivers/tty/isicom.c | 72 +++++++++++++++----------------------------- 1 file changed, 25 insertions(+), 47 deletions(-) diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index 8d96e86966f1b..e04a43e89f6b9 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c @@ -1091,34 +1091,33 @@ static int isicom_tiocmset(struct tty_struct *tty, } static int isicom_set_serial_info(struct tty_struct *tty, - struct serial_struct __user *info) + struct serial_struct *ss) { struct isi_port *port = tty->driver_data; - struct serial_struct newinfo; int reconfig_port; - if (copy_from_user(&newinfo, info, sizeof(newinfo))) - return -EFAULT; + if (isicom_paranoia_check(port, tty->name, "isicom_ioctl")) + return -ENODEV; mutex_lock(&port->port.mutex); reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) != - (newinfo.flags & ASYNC_SPD_MASK)); + (ss->flags & ASYNC_SPD_MASK)); if (!capable(CAP_SYS_ADMIN)) { - if ((newinfo.close_delay != port->port.close_delay) || - (newinfo.closing_wait != port->port.closing_wait) || - ((newinfo.flags & ~ASYNC_USR_MASK) != + if ((ss->close_delay != port->port.close_delay) || + (ss->closing_wait != port->port.closing_wait) || + ((ss->flags & ~ASYNC_USR_MASK) != (port->port.flags & ~ASYNC_USR_MASK))) { mutex_unlock(&port->port.mutex); return -EPERM; } port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | - (newinfo.flags & ASYNC_USR_MASK)); + (ss->flags & ASYNC_USR_MASK)); } else { - port->port.close_delay = newinfo.close_delay; - port->port.closing_wait = newinfo.closing_wait; + port->port.close_delay = ss->close_delay; + port->port.closing_wait = ss->closing_wait; port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) | - (newinfo.flags & ASYNC_FLAGS)); + (ss->flags & ASYNC_FLAGS)); } if (reconfig_port) { unsigned long flags; @@ -1130,46 +1129,24 @@ static int isicom_set_serial_info(struct tty_struct *tty, return 0; } -static int isicom_get_serial_info(struct isi_port *port, - struct serial_struct __user *info) -{ - struct serial_struct out_info; - - mutex_lock(&port->port.mutex); - memset(&out_info, 0, sizeof(out_info)); -/* out_info.type = ? */ - out_info.line = port - isi_ports; - out_info.port = port->card->base; - out_info.irq = port->card->irq; - out_info.flags = port->port.flags; -/* out_info.baud_base = ? */ - out_info.close_delay = port->port.close_delay; - out_info.closing_wait = port->port.closing_wait; - mutex_unlock(&port->port.mutex); - if (copy_to_user(info, &out_info, sizeof(out_info))) - return -EFAULT; - return 0; -} - -static int isicom_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) +static int isicom_get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { struct isi_port *port = tty->driver_data; - void __user *argp = (void __user *)arg; if (isicom_paranoia_check(port, tty->name, "isicom_ioctl")) return -ENODEV; - switch (cmd) { - case TIOCGSERIAL: - return isicom_get_serial_info(port, argp); - - case TIOCSSERIAL: - return isicom_set_serial_info(tty, argp); - - default: - return -ENOIOCTLCMD; - } + mutex_lock(&port->port.mutex); +/* ss->type = ? */ + ss->line = port - isi_ports; + ss->port = port->card->base; + ss->irq = port->card->irq; + ss->flags = port->port.flags; +/* ss->baud_base = ? */ + ss->close_delay = port->port.close_delay; + ss->closing_wait = port->port.closing_wait; + mutex_unlock(&port->port.mutex); return 0; } @@ -1273,7 +1250,6 @@ static const struct tty_operations isicom_ops = { .flush_chars = isicom_flush_chars, .write_room = isicom_write_room, .chars_in_buffer = isicom_chars_in_buffer, - .ioctl = isicom_ioctl, .set_termios = isicom_set_termios, .throttle = isicom_throttle, .unthrottle = isicom_unthrottle, @@ -1284,6 +1260,8 @@ static const struct tty_operations isicom_ops = { .tiocmget = isicom_tiocmget, .tiocmset = isicom_tiocmset, .break_ctl = isicom_send_break, + .get_serial = isicom_get_serial_info, + .set_serial = isicom_set_serial_info, }; static const struct tty_port_operations isicom_port_ops = { From 1c729ab15a0eeff57aafab704161f8d3663b2854 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 22:01:00 -0400 Subject: [PATCH 13/53] moxa: switch to ->[sg]et_serial() Pointless dead assignments in moxa_set_serial_info() killed off; they would've been a bug, if not for the fact that user-settable flags had never been used in that driver. Bogus from day 1, though... Signed-off-by: Al Viro --- drivers/tty/moxa.c | 79 +++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 250a19f042d74..3a1a5e0ee93f1 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -221,8 +221,8 @@ static int MoxaPortRxQueue(struct moxa_port *); static int MoxaPortTxFree(struct moxa_port *); static void MoxaPortTxDisable(struct moxa_port *); static void MoxaPortTxEnable(struct moxa_port *); -static int moxa_get_serial_info(struct moxa_port *, struct serial_struct __user *); -static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *); +static int moxa_get_serial_info(struct tty_struct *, struct serial_struct *); +static int moxa_set_serial_info(struct tty_struct *, struct serial_struct *); static void MoxaSetFifo(struct moxa_port *port, int enable); /* @@ -375,16 +375,6 @@ static int moxa_ioctl(struct tty_struct *tty, } break; } - case TIOCGSERIAL: - mutex_lock(&ch->port.mutex); - ret = moxa_get_serial_info(ch, argp); - mutex_unlock(&ch->port.mutex); - break; - case TIOCSSERIAL: - mutex_lock(&ch->port.mutex); - ret = moxa_set_serial_info(ch, argp); - mutex_unlock(&ch->port.mutex); - break; default: ret = -ENOIOCTLCMD; } @@ -415,6 +405,8 @@ static const struct tty_operations moxa_ops = { .break_ctl = moxa_break_ctl, .tiocmget = moxa_tiocmget, .tiocmset = moxa_tiocmset, + .set_serial = moxa_set_serial_info, + .get_serial = moxa_get_serial_info, }; static const struct tty_port_operations moxa_port_ops = { @@ -2034,46 +2026,55 @@ static void MoxaPortTxEnable(struct moxa_port *port) moxafunc(port->tableAddr, FC_SetXonState, Magic_code); } -static int moxa_get_serial_info(struct moxa_port *info, - struct serial_struct __user *retinfo) +static int moxa_get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct tmp = { - .type = info->type, - .line = info->port.tty->index, - .flags = info->port.flags, - .baud_base = 921600, - .close_delay = info->port.close_delay - }; - return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; + struct moxa_port *info = tty->driver_data; + + if (tty->index == MAX_PORTS) + return -EINVAL; + if (!info) + return -ENODEV; + mutex_lock(&info->port.mutex); + ss->type = info->type, + ss->line = info->port.tty->index, + ss->flags = info->port.flags, + ss->baud_base = 921600, + ss->close_delay = info->port.close_delay; + mutex_unlock(&info->port.mutex); + return 0; } -static int moxa_set_serial_info(struct moxa_port *info, - struct serial_struct __user *new_info) +static int moxa_set_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct new_serial; + struct moxa_port *info = tty->driver_data; - if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) - return -EFAULT; + if (tty->index == MAX_PORTS) + return -EINVAL; + if (!info) + return -ENODEV; - if (new_serial.irq != 0 || new_serial.port != 0 || - new_serial.custom_divisor != 0 || - new_serial.baud_base != 921600) + if (ss->irq != 0 || ss->port != 0 || + ss->custom_divisor != 0 || + ss->baud_base != 921600) return -EPERM; + mutex_lock(&info->port.mutex); if (!capable(CAP_SYS_ADMIN)) { - if (((new_serial.flags & ~ASYNC_USR_MASK) != - (info->port.flags & ~ASYNC_USR_MASK))) + if (((ss->flags & ~ASYNC_USR_MASK) != + (info->port.flags & ~ASYNC_USR_MASK))) { + mutex_unlock(&info->port.mutex); return -EPERM; - } else - info->port.close_delay = new_serial.close_delay * HZ / 100; - - new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS); - new_serial.flags |= (info->port.flags & ASYNC_FLAGS); + } + } + info->port.close_delay = ss->close_delay * HZ / 100; - MoxaSetFifo(info, new_serial.type == PORT_16550A); + MoxaSetFifo(info, ss->type == PORT_16550A); - info->type = new_serial.type; + info->type = ss->type; + mutex_unlock(&info->port.mutex); return 0; } From 6da5b587631cb729de917a0ba629b139781cb3ef Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 22:22:06 -0400 Subject: [PATCH 14/53] mxser: switch to ->[sg]et_serial() Signed-off-by: Al Viro --- drivers/tty/mxser.c | 97 ++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 46 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 8bc15cb67a58b..9d00ff5ef9611 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1207,76 +1207,90 @@ static int mxser_chars_in_buffer(struct tty_struct *tty) * ------------------------------------------------------------ */ static int mxser_get_serial_info(struct tty_struct *tty, - struct serial_struct __user *retinfo) + struct serial_struct *ss) { struct mxser_port *info = tty->driver_data; - struct serial_struct tmp = { - .type = info->type, - .line = tty->index, - .port = info->ioaddr, - .irq = info->board->irq, - .flags = info->port.flags, - .baud_base = info->baud_base, - .close_delay = info->port.close_delay, - .closing_wait = info->port.closing_wait, - .custom_divisor = info->custom_divisor, - }; - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; + struct tty_port *port = &info->port; + + if (tty->index == MXSER_PORTS) + return -ENOTTY; + + mutex_lock(&port->mutex); + ss->type = info->type, + ss->line = tty->index, + ss->port = info->ioaddr, + ss->irq = info->board->irq, + ss->flags = info->port.flags, + ss->baud_base = info->baud_base, + ss->close_delay = info->port.close_delay, + ss->closing_wait = info->port.closing_wait, + ss->custom_divisor = info->custom_divisor, + mutex_unlock(&port->mutex); return 0; } static int mxser_set_serial_info(struct tty_struct *tty, - struct serial_struct __user *new_info) + struct serial_struct *ss) { struct mxser_port *info = tty->driver_data; struct tty_port *port = &info->port; - struct serial_struct new_serial; speed_t baud; unsigned long sl_flags; unsigned int flags; int retval = 0; - if (!new_info || !info->ioaddr) + if (tty->index == MXSER_PORTS) + return -ENOTTY; + if (tty_io_error(tty)) + return -EIO; + + mutex_lock(&port->mutex); + if (!info->ioaddr) { + mutex_unlock(&port->mutex); return -ENODEV; - if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) - return -EFAULT; + } - if (new_serial.irq != info->board->irq || - new_serial.port != info->ioaddr) + if (ss->irq != info->board->irq || + ss->port != info->ioaddr) { + mutex_unlock(&port->mutex); return -EINVAL; + } flags = port->flags & ASYNC_SPD_MASK; if (!capable(CAP_SYS_ADMIN)) { - if ((new_serial.baud_base != info->baud_base) || - (new_serial.close_delay != info->port.close_delay) || - ((new_serial.flags & ~ASYNC_USR_MASK) != (info->port.flags & ~ASYNC_USR_MASK))) + if ((ss->baud_base != info->baud_base) || + (ss->close_delay != info->port.close_delay) || + ((ss->flags & ~ASYNC_USR_MASK) != (info->port.flags & ~ASYNC_USR_MASK))) { + mutex_unlock(&port->mutex); return -EPERM; + } info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); + (ss->flags & ASYNC_USR_MASK)); } else { /* * OK, past this point, all the error checking has been done. * At this point, we start making changes..... */ port->flags = ((port->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - port->close_delay = new_serial.close_delay * HZ / 100; - port->closing_wait = new_serial.closing_wait * HZ / 100; + (ss->flags & ASYNC_FLAGS)); + port->close_delay = ss->close_delay * HZ / 100; + port->closing_wait = ss->closing_wait * HZ / 100; port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && - (new_serial.baud_base != info->baud_base || - new_serial.custom_divisor != + (ss->baud_base != info->baud_base || + ss->custom_divisor != info->custom_divisor)) { - if (new_serial.custom_divisor == 0) + if (ss->custom_divisor == 0) { + mutex_unlock(&port->mutex); return -EINVAL; - baud = new_serial.baud_base / new_serial.custom_divisor; + } + baud = ss->baud_base / ss->custom_divisor; tty_encode_baud_rate(tty, baud, baud); } } - info->type = new_serial.type; + info->type = ss->type; process_txrx_fifo(info); @@ -1291,6 +1305,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, if (retval == 0) tty_port_set_initialized(port, 1); } + mutex_unlock(&port->mutex); return retval; } @@ -1660,11 +1675,9 @@ static int mxser_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct mxser_port *info = tty->driver_data; - struct tty_port *port = &info->port; struct async_icount cnow; unsigned long flags; void __user *argp = (void __user *)arg; - int retval; if (tty->index == MXSER_PORTS) return mxser_ioctl_special(cmd, argp); @@ -1708,20 +1721,10 @@ static int mxser_ioctl(struct tty_struct *tty, return 0; } - if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && tty_io_error(tty)) + if (cmd != TIOCMIWAIT && tty_io_error(tty)) return -EIO; switch (cmd) { - case TIOCGSERIAL: - mutex_lock(&port->mutex); - retval = mxser_get_serial_info(tty, argp); - mutex_unlock(&port->mutex); - return retval; - case TIOCSSERIAL: - mutex_lock(&port->mutex); - retval = mxser_set_serial_info(tty, argp); - mutex_unlock(&port->mutex); - return retval; case TIOCSERGETLSR: /* Get line status register */ return mxser_get_lsr_info(info, argp); /* @@ -2325,6 +2328,8 @@ static const struct tty_operations mxser_ops = { .wait_until_sent = mxser_wait_until_sent, .tiocmget = mxser_tiocmget, .tiocmset = mxser_tiocmset, + .set_serial = mxser_set_serial_info, + .get_serial = mxser_get_serial_info, .get_icount = mxser_get_icount, }; From 5099d234a52a0a9a9c6acbe8c9ee286a73ac1aed Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 22:29:55 -0400 Subject: [PATCH 15/53] serial_core: switch to ->[sg]et_serial() Signed-off-by: Al Viro --- drivers/tty/serial/serial_core.c | 38 ++++++++++---------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 80bb56facfb68..2c8162b8ebf2c 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -778,17 +778,13 @@ static int uart_get_info(struct tty_port *port, struct serial_struct *retinfo) return ret; } -static int uart_get_info_user(struct tty_port *port, - struct serial_struct __user *retinfo) +static int uart_get_info_user(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct tmp; - - if (uart_get_info(port, &tmp) < 0) - return -EIO; + struct uart_state *state = tty->driver_data; + struct tty_port *port = &state->port; - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - return 0; + return uart_get_info(port, ss) < 0 ? -EIO : 0; } static int uart_set_info(struct tty_struct *tty, struct tty_port *port, @@ -990,16 +986,13 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, return retval; } -static int uart_set_info_user(struct tty_struct *tty, struct uart_state *state, - struct serial_struct __user *newinfo) +static int uart_set_info_user(struct tty_struct *tty, struct serial_struct *ss) { - struct serial_struct new_serial; + struct uart_state *state = tty->driver_data; struct tty_port *port = &state->port; int retval; - if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) - return -EFAULT; - + down_write(&tty->termios_rwsem); /* * This semaphore protects port->count. It is also * very useful to prevent opens. Also, take the @@ -1008,8 +1001,9 @@ static int uart_set_info_user(struct tty_struct *tty, struct uart_state *state, * under us. */ mutex_lock(&port->mutex); - retval = uart_set_info(tty, port, state, &new_serial); + retval = uart_set_info(tty, port, state, ss); mutex_unlock(&port->mutex); + up_write(&tty->termios_rwsem); return retval; } @@ -1325,16 +1319,6 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) * These ioctls don't rely on the hardware to be present. */ switch (cmd) { - case TIOCGSERIAL: - ret = uart_get_info_user(port, uarg); - break; - - case TIOCSSERIAL: - down_write(&tty->termios_rwsem); - ret = uart_set_info_user(tty, state, uarg); - up_write(&tty->termios_rwsem); - break; - case TIOCSERCONFIG: down_write(&tty->termios_rwsem); ret = uart_do_autoconfig(tty, state); @@ -2413,6 +2397,8 @@ static const struct tty_operations uart_ops = { #endif .tiocmget = uart_tiocmget, .tiocmset = uart_tiocmset, + .set_serial = uart_set_info_user, + .get_serial = uart_get_info_user, .get_icount = uart_get_icount, #ifdef CONFIG_CONSOLE_POLL .poll_init = uart_poll_init, From 6a9daed31cc8dc1ca0b3d25f85426adbd2112293 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 23:22:59 -0400 Subject: [PATCH 16/53] rfcomm: get rid of mentioning TIOC[SG]SERIAL no support there Signed-off-by: Al Viro --- net/bluetooth/rfcomm/tty.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 5e44d842cc5d0..ba4f59389405d 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -839,14 +839,6 @@ static int rfcomm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned l BT_DBG("TIOCMIWAIT"); break; - case TIOCGSERIAL: - BT_ERR("TIOCGSERIAL is not supported"); - return -ENOIOCTLCMD; - - case TIOCSSERIAL: - BT_ERR("TIOCSSERIAL is not supported"); - return -ENOIOCTLCMD; - case TIOCSERGSTRUCT: BT_ERR("TIOCSERGSTRUCT is not supported"); return -ENOIOCTLCMD; From 81732b26e05994552f347746eb11762e986079a0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 23:28:07 -0400 Subject: [PATCH 17/53] usb-serial: begin switching to ->[sg]et_serial() add such methods for usb_serial_driver, provide tty_operations ->[sg]et_serial() calling those. For now the lack of methods in driver means ENOIOCTLCMD from usb-serial ->[sg]et_serial(), making tty_ioctl() fall back to calling ->ioctl(). Once all drivers are converted, we'll be returning -ENOTTY instead, completing the switchover. Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/usb/serial/usb-serial.c | 20 ++++++++++++++++++++ include/linux/usb/serial.h | 2 ++ 2 files changed, 22 insertions(+) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index f7aaa7f079e1a..0f96d82fc575c 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -396,6 +396,24 @@ static void serial_unthrottle(struct tty_struct *tty) port->serial->type->unthrottle(tty); } +static int serial_get_serial(struct tty_struct *tty, struct serial_struct *ss) +{ + struct usb_serial_port *port = tty->driver_data; + + if (port->serial->type->get_serial) + return port->serial->type->get_serial(tty, ss); + return -ENOIOCTLCMD; +} + +static int serial_set_serial(struct tty_struct *tty, struct serial_struct *ss) +{ + struct usb_serial_port *port = tty->driver_data; + + if (port->serial->type->set_serial) + return port->serial->type->set_serial(tty, ss); + return -ENOIOCTLCMD; +} + static int serial_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { @@ -1177,6 +1195,8 @@ static const struct tty_operations serial_ops = { .tiocmget = serial_tiocmget, .tiocmset = serial_tiocmset, .get_icount = serial_get_icount, + .set_serial = serial_set_serial, + .get_serial = serial_get_serial, .cleanup = serial_cleanup, .install = serial_install, .proc_show = serial_proc_show, diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 106551a5616ed..1c19f77ed5411 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -285,6 +285,8 @@ struct usb_serial_driver { int (*write_room)(struct tty_struct *tty); int (*ioctl)(struct tty_struct *tty, unsigned int cmd, unsigned long arg); + int (*get_serial)(struct tty_struct *tty, struct serial_struct *ss); + int (*set_serial)(struct tty_struct *tty, struct serial_struct *ss); void (*set_termios)(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); void (*break_ctl)(struct tty_struct *tty, int break_state); From 99f75a1fcd865d39b5f2b99ce067bf5a2259e03a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 23:33:40 -0400 Subject: [PATCH 18/53] cdc-acm: switch to ->[sg]et_serial() Signed-off-by: Al Viro --- drivers/usb/class/cdc-acm.c | 41 +++++++++++++------------------------ 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 27346d69f3938..5fd59a58de929 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -956,37 +956,28 @@ static int acm_tty_tiocmset(struct tty_struct *tty, return acm_set_control(acm, acm->ctrlout = newctrl); } -static int get_serial_info(struct acm *acm, struct serial_struct __user *info) +static int get_serial_info(struct tty_struct *tty, struct serial_struct *ss) { - struct serial_struct tmp; + struct acm *acm = tty->driver_data; - memset(&tmp, 0, sizeof(tmp)); - tmp.xmit_fifo_size = acm->writesize; - tmp.baud_base = le32_to_cpu(acm->line.dwDTERate); - tmp.close_delay = acm->port.close_delay / 10; - tmp.closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? + ss->xmit_fifo_size = acm->writesize; + ss->baud_base = le32_to_cpu(acm->line.dwDTERate); + ss->close_delay = acm->port.close_delay / 10; + ss->closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? ASYNC_CLOSING_WAIT_NONE : acm->port.closing_wait / 10; - - if (copy_to_user(info, &tmp, sizeof(tmp))) - return -EFAULT; - else - return 0; + return 0; } -static int set_serial_info(struct acm *acm, - struct serial_struct __user *newinfo) +static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss) { - struct serial_struct new_serial; + struct acm *acm = tty->driver_data; unsigned int closing_wait, close_delay; int retval = 0; - if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) - return -EFAULT; - - close_delay = new_serial.close_delay * 10; - closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? - ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10; + close_delay = ss->close_delay * 10; + closing_wait = ss->closing_wait == ASYNC_CLOSING_WAIT_NONE ? + ASYNC_CLOSING_WAIT_NONE : ss->closing_wait * 10; mutex_lock(&acm->port.mutex); @@ -1071,12 +1062,6 @@ static int acm_tty_ioctl(struct tty_struct *tty, int rv = -ENOIOCTLCMD; switch (cmd) { - case TIOCGSERIAL: /* gets serial port data */ - rv = get_serial_info(acm, (struct serial_struct __user *) arg); - break; - case TIOCSSERIAL: - rv = set_serial_info(acm, (struct serial_struct __user *) arg); - break; case TIOCMIWAIT: rv = usb_autopm_get_interface(acm->control); if (rv < 0) { @@ -1998,6 +1983,8 @@ static const struct tty_operations acm_ops = { .set_termios = acm_tty_set_termios, .tiocmget = acm_tty_tiocmget, .tiocmset = acm_tty_tiocmset, + .get_serial = get_serial_info, + .set_serial = set_serial_info, .get_icount = acm_tty_get_icount, }; From aadcd0a178be1770394259d2c345b91b9b6be048 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 23:35:20 -0400 Subject: [PATCH 19/53] ark3116: switch to ->get_serial() Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/usb/serial/ark3116.c | 38 ++++++++---------------------------- 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 7796ad8e33c6e..ff38aa8963cf8 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -397,38 +397,16 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) return result; } -static int ark3116_get_serial_info(struct usb_serial_port *port, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - - memset(&tmp, 0, sizeof(tmp)); - - tmp.type = PORT_16654; - tmp.line = port->minor; - tmp.port = port->port_number; - tmp.baud_base = 460800; - - if (copy_to_user(retinfo, &tmp, sizeof(tmp))) - return -EFAULT; - - return 0; -} - -static int ark3116_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) +static int ark3116_get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { struct usb_serial_port *port = tty->driver_data; - void __user *user_arg = (void __user *)arg; - - switch (cmd) { - case TIOCGSERIAL: - return ark3116_get_serial_info(port, user_arg); - default: - break; - } - return -ENOIOCTLCMD; + ss->type = PORT_16654; + ss->line = port->minor; + ss->port = port->port_number; + ss->baud_base = 460800; + return 0; } static int ark3116_tiocmget(struct tty_struct *tty) @@ -668,7 +646,7 @@ static struct usb_serial_driver ark3116_device = { .port_remove = ark3116_port_remove, .set_termios = ark3116_set_termios, .init_termios = ark3116_init_termios, - .ioctl = ark3116_ioctl, + .get_serial = ark3116_get_serial_info, .tiocmget = ark3116_tiocmget, .tiocmset = ark3116_tiocmset, .tiocmiwait = usb_serial_generic_tiocmiwait, From 056abede09a779acda8e24b941d62bf0fed33f64 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 23:37:01 -0400 Subject: [PATCH 20/53] f81232: switch to ->get_serial() Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/usb/serial/f81232.c | 36 ++++++++---------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 96036f87b1ded..0dcdcb4b2cde5 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -583,36 +583,16 @@ static int f81232_carrier_raised(struct usb_serial_port *port) return 0; } -static int f81232_get_serial_info(struct usb_serial_port *port, - unsigned long arg) -{ - struct serial_struct ser; - - memset(&ser, 0, sizeof(ser)); - - ser.type = PORT_16550A; - ser.line = port->minor; - ser.port = port->port_number; - ser.baud_base = F81232_MAX_BAUDRATE; - - if (copy_to_user((void __user *)arg, &ser, sizeof(ser))) - return -EFAULT; - - return 0; -} - -static int f81232_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) +static int f81232_get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { struct usb_serial_port *port = tty->driver_data; - switch (cmd) { - case TIOCGSERIAL: - return f81232_get_serial_info(port, arg); - default: - break; - } - return -ENOIOCTLCMD; + ss->type = PORT_16550A; + ss->line = port->minor; + ss->port = port->port_number; + ss->baud_base = F81232_MAX_BAUDRATE; + return 0; } static void f81232_interrupt_work(struct work_struct *work) @@ -665,7 +645,7 @@ static struct usb_serial_driver f81232_device = { .close = f81232_close, .dtr_rts = f81232_dtr_rts, .carrier_raised = f81232_carrier_raised, - .ioctl = f81232_ioctl, + .get_serial = f81232_get_serial_info, .break_ctl = f81232_break_ctl, .set_termios = f81232_set_termios, .tiocmget = f81232_tiocmget, From c8f97e77d53ff0717a1175b3cdefa497127347f9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 23:38:49 -0400 Subject: [PATCH 21/53] f81534: switch to ->get_serial() Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/usb/serial/f81534.c | 38 ++++++++----------------------------- 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c index 4dfbff20bda4c..380933db34dd5 100644 --- a/drivers/usb/serial/f81534.c +++ b/drivers/usb/serial/f81534.c @@ -1139,43 +1139,21 @@ static void f81534_close(struct usb_serial_port *port) mutex_unlock(&serial_priv->urb_mutex); } -static int f81534_get_serial_info(struct usb_serial_port *port, - struct serial_struct __user *retinfo) +static int f81534_get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { + struct usb_serial_port *port = tty->driver_data; struct f81534_port_private *port_priv; - struct serial_struct tmp; port_priv = usb_get_serial_port_data(port); - memset(&tmp, 0, sizeof(tmp)); - - tmp.type = PORT_16550A; - tmp.port = port->port_number; - tmp.line = port->minor; - tmp.baud_base = port_priv->baud_base; - - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - + ss->type = PORT_16550A; + ss->port = port->port_number; + ss->line = port->minor; + ss->baud_base = port_priv->baud_base; return 0; } -static int f81534_ioctl(struct tty_struct *tty, unsigned int cmd, - unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - struct serial_struct __user *buf = (struct serial_struct __user *)arg; - - switch (cmd) { - case TIOCGSERIAL: - return f81534_get_serial_info(port, buf); - default: - break; - } - - return -ENOIOCTLCMD; -} - static void f81534_process_per_serial_block(struct usb_serial_port *port, u8 *data) { @@ -1581,7 +1559,7 @@ static struct usb_serial_driver f81534_device = { .break_ctl = f81534_break_ctl, .dtr_rts = f81534_dtr_rts, .process_read_urb = f81534_process_read_urb, - .ioctl = f81534_ioctl, + .get_serial = f81534_get_serial_info, .tiocmget = f81534_tiocmget, .tiocmset = f81534_tiocmset, .write_bulk_callback = f81534_write_usb_callback, From 3ae36bed3a93f5b871341be9b2e39aaff0d2559f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 23:42:36 -0400 Subject: [PATCH 22/53] fdti_sio: switch to ->[sg]et_serial() Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/usb/serial/ftdi_sio.c | 48 +++++++++++++++-------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index b5cef322826f1..758ba789e997f 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1055,6 +1055,10 @@ static int ftdi_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static int ftdi_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); +static int get_serial_info(struct tty_struct *tty, + struct serial_struct *ss); +static int set_serial_info(struct tty_struct *tty, + struct serial_struct *ss); static void ftdi_break_ctl(struct tty_struct *tty, int break_state); static bool ftdi_tx_empty(struct usb_serial_port *port); static int ftdi_get_modem_status(struct usb_serial_port *port, @@ -1091,6 +1095,8 @@ static struct usb_serial_driver ftdi_sio_device = { .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, .ioctl = ftdi_ioctl, + .get_serial = get_serial_info, + .set_serial = set_serial_info, .set_termios = ftdi_set_termios, .break_ctl = ftdi_break_ctl, .tx_empty = ftdi_tx_empty, @@ -1443,48 +1449,42 @@ static int read_latency_timer(struct usb_serial_port *port) return 0; } -static int get_serial_info(struct usb_serial_port *port, - struct serial_struct __user *retinfo) +static int get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { + struct usb_serial_port *port = tty->driver_data; struct ftdi_private *priv = usb_get_serial_port_data(port); - struct serial_struct tmp; - memset(&tmp, 0, sizeof(tmp)); - tmp.flags = priv->flags; - tmp.baud_base = priv->baud_base; - tmp.custom_divisor = priv->custom_divisor; - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; + ss->flags = priv->flags; + ss->baud_base = priv->baud_base; + ss->custom_divisor = priv->custom_divisor; return 0; } static int set_serial_info(struct tty_struct *tty, - struct usb_serial_port *port, struct serial_struct __user *newinfo) + struct serial_struct *ss) { + struct usb_serial_port *port = tty->driver_data; struct ftdi_private *priv = usb_get_serial_port_data(port); - struct serial_struct new_serial; struct ftdi_private old_priv; - if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) - return -EFAULT; - mutex_lock(&priv->cfg_lock); old_priv = *priv; /* Do error checking and permission checking */ if (!capable(CAP_SYS_ADMIN)) { - if ((new_serial.flags ^ priv->flags) & ~ASYNC_USR_MASK) { + if ((ss->flags ^ priv->flags) & ~ASYNC_USR_MASK) { mutex_unlock(&priv->cfg_lock); return -EPERM; } priv->flags = ((priv->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - priv->custom_divisor = new_serial.custom_divisor; + (ss->flags & ASYNC_USR_MASK)); + priv->custom_divisor = ss->custom_divisor; goto check_and_exit; } - if (new_serial.baud_base != priv->baud_base) { + if (ss->baud_base != priv->baud_base) { mutex_unlock(&priv->cfg_lock); return -EINVAL; } @@ -1492,8 +1492,8 @@ static int set_serial_info(struct tty_struct *tty, /* Make the changes - these are privileged changes! */ priv->flags = ((priv->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - priv->custom_divisor = new_serial.custom_divisor; + (ss->flags & ASYNC_FLAGS)); + priv->custom_divisor = ss->custom_divisor; check_and_exit: write_latency_timer(port); @@ -1507,10 +1507,8 @@ static int set_serial_info(struct tty_struct *tty, dev_warn_ratelimited(&port->dev, "use of SPD flags is deprecated\n"); change_speed(tty, port); - mutex_unlock(&priv->cfg_lock); } - else - mutex_unlock(&priv->cfg_lock); + mutex_unlock(&priv->cfg_lock); return 0; } @@ -2452,10 +2450,6 @@ static int ftdi_ioctl(struct tty_struct *tty, void __user *argp = (void __user *)arg; switch (cmd) { - case TIOCGSERIAL: - return get_serial_info(port, argp); - case TIOCSSERIAL: - return set_serial_info(tty, port, argp); case TIOCSERGETLSR: return get_lsr_info(port, argp); default: From e27235eda550a58ab8884836a190b3c1b3940e92 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 23:45:02 -0400 Subject: [PATCH 23/53] io_edgeport: switch to ->get_serial() Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/usb/serial/io_edgeport.c | 37 ++++++++++++++------------------ 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 97c69d373ca65..4ca31c0e41745 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -1637,24 +1637,20 @@ static int edge_tiocmget(struct tty_struct *tty) return result; } -static int get_serial_info(struct edgeport_port *edge_port, - struct serial_struct __user *retinfo) +static int get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct tmp; - - memset(&tmp, 0, sizeof(tmp)); - - tmp.type = PORT_16550A; - tmp.line = edge_port->port->minor; - tmp.port = edge_port->port->port_number; - tmp.irq = 0; - tmp.xmit_fifo_size = edge_port->maxTxCredits; - tmp.baud_base = 9600; - tmp.close_delay = 5*HZ; - tmp.closing_wait = 30*HZ; + struct usb_serial_port *port = tty->driver_data; + struct edgeport_port *edge_port = usb_get_serial_port_data(port); - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; + ss->type = PORT_16550A; + ss->line = edge_port->port->minor; + ss->port = edge_port->port->port_number; + ss->irq = 0; + ss->xmit_fifo_size = edge_port->maxTxCredits; + ss->baud_base = 9600; + ss->close_delay = 5*HZ; + ss->closing_wait = 30*HZ; return 0; } @@ -1667,17 +1663,12 @@ static int edge_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; - DEFINE_WAIT(wait); struct edgeport_port *edge_port = usb_get_serial_port_data(port); switch (cmd) { case TIOCSERGETLSR: dev_dbg(&port->dev, "%s TIOCSERGETLSR\n", __func__); return get_lsr_info(edge_port, (unsigned int __user *) arg); - - case TIOCGSERIAL: - dev_dbg(&port->dev, "%s TIOCGSERIAL\n", __func__); - return get_serial_info(edge_port, (struct serial_struct __user *) arg); } return -ENOIOCTLCMD; } @@ -3126,6 +3117,7 @@ static struct usb_serial_driver edgeport_2port_device = { .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, .tiocmset = edge_tiocmset, + .get_serial = get_serial_info, .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, .write = edge_write, @@ -3161,6 +3153,7 @@ static struct usb_serial_driver edgeport_4port_device = { .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, .tiocmset = edge_tiocmset, + .get_serial = get_serial_info, .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, .write = edge_write, @@ -3196,6 +3189,7 @@ static struct usb_serial_driver edgeport_8port_device = { .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, .tiocmset = edge_tiocmset, + .get_serial = get_serial_info, .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, .write = edge_write, @@ -3231,6 +3225,7 @@ static struct usb_serial_driver epic_device = { .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, .tiocmset = edge_tiocmset, + .get_serial = get_serial_info, .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, .write = edge_write, From 2a5357e56360a076867a21b4914a5340399eff5b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 00:17:54 -0400 Subject: [PATCH 24/53] io_ti: switch to ->get_serial() Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/usb/serial/io_ti.c | 47 ++++++++++++-------------------------- 1 file changed, 14 insertions(+), 33 deletions(-) diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 6d1d6efa30554..c327d4cf79285 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2437,47 +2437,28 @@ static int edge_tiocmget(struct tty_struct *tty) return result; } -static int get_serial_info(struct edgeport_port *edge_port, - struct serial_struct __user *retinfo) +static int get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct tmp; + struct usb_serial_port *port = tty->driver_data; + struct edgeport_port *edge_port = usb_get_serial_port_data(port); unsigned cwait; cwait = edge_port->port->port.closing_wait; if (cwait != ASYNC_CLOSING_WAIT_NONE) cwait = jiffies_to_msecs(cwait) / 10; - memset(&tmp, 0, sizeof(tmp)); - - tmp.type = PORT_16550A; - tmp.line = edge_port->port->minor; - tmp.port = edge_port->port->port_number; - tmp.irq = 0; - tmp.xmit_fifo_size = edge_port->port->bulk_out_size; - tmp.baud_base = 9600; - tmp.close_delay = 5*HZ; - tmp.closing_wait = cwait; - - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; + ss->type = PORT_16550A; + ss->line = edge_port->port->minor; + ss->port = edge_port->port->port_number; + ss->irq = 0; + ss->xmit_fifo_size = edge_port->port->bulk_out_size; + ss->baud_base = 9600; + ss->close_delay = 5*HZ; + ss->closing_wait = cwait; return 0; } -static int edge_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - - switch (cmd) { - case TIOCGSERIAL: - dev_dbg(&port->dev, "%s - TIOCGSERIAL\n", __func__); - return get_serial_info(edge_port, - (struct serial_struct __user *) arg); - } - return -ENOIOCTLCMD; -} - static void edge_break(struct tty_struct *tty, int break_state) { struct usb_serial_port *port = tty->driver_data; @@ -2738,7 +2719,7 @@ static struct usb_serial_driver edgeport_1port_device = { .release = edge_release, .port_probe = edge_port_probe, .port_remove = edge_port_remove, - .ioctl = edge_ioctl, + .get_serial = get_serial_info, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, .tiocmset = edge_tiocmset, @@ -2777,7 +2758,7 @@ static struct usb_serial_driver edgeport_2port_device = { .release = edge_release, .port_probe = edge_port_probe, .port_remove = edge_port_remove, - .ioctl = edge_ioctl, + .get_serial = get_serial_info, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, .tiocmset = edge_tiocmset, From 7cf3e600a07bc73823bf0ae0309e59dafd303817 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 00:20:17 -0400 Subject: [PATCH 25/53] mos7720: switch to ->get_serial() Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/usb/serial/mos7720.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 4c06357b3ef8d..fc52ac75fbf66 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -1786,24 +1786,20 @@ static int mos7720_tiocmset(struct tty_struct *tty, return 0; } -static int get_serial_info(struct moschip_port *mos7720_port, - struct serial_struct __user *retinfo) +static int get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct tmp; - - memset(&tmp, 0, sizeof(tmp)); - - tmp.type = PORT_16550A; - tmp.line = mos7720_port->port->minor; - tmp.port = mos7720_port->port->port_number; - tmp.irq = 0; - tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE; - tmp.baud_base = 9600; - tmp.close_delay = 5*HZ; - tmp.closing_wait = 30*HZ; + struct usb_serial_port *port = tty->driver_data; + struct moschip_port *mos7720_port = usb_get_serial_port_data(port); - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; + ss->type = PORT_16550A; + ss->line = mos7720_port->port->minor; + ss->port = mos7720_port->port->port_number; + ss->irq = 0; + ss->xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE; + ss->baud_base = 9600; + ss->close_delay = 5*HZ; + ss->closing_wait = 30*HZ; return 0; } @@ -1822,11 +1818,6 @@ static int mos7720_ioctl(struct tty_struct *tty, dev_dbg(&port->dev, "%s TIOCSERGETLSR\n", __func__); return get_lsr_info(tty, mos7720_port, (unsigned int __user *)arg); - - case TIOCGSERIAL: - dev_dbg(&port->dev, "%s TIOCGSERIAL\n", __func__); - return get_serial_info(mos7720_port, - (struct serial_struct __user *)arg); } return -ENOIOCTLCMD; @@ -1963,6 +1954,7 @@ static struct usb_serial_driver moschip7720_2port_driver = { .ioctl = mos7720_ioctl, .tiocmget = mos7720_tiocmget, .tiocmset = mos7720_tiocmset, + .get_serial = get_serial_info, .set_termios = mos7720_set_termios, .write = mos7720_write, .write_room = mos7720_write_room, From b27ef409b415099aa2c540630db03ea84f45c5cc Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 07:20:09 -0400 Subject: [PATCH 26/53] mos7840: switch to ->get_serial() Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/usb/serial/mos7840.c | 39 ++++++++++++------------------------ 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index b42bad85097ae..88828b4b8c446 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -1931,27 +1931,20 @@ static int mos7840_get_lsr_info(struct tty_struct *tty, * function to get information about serial port *****************************************************************************/ -static int mos7840_get_serial_info(struct moschip_port *mos7840_port, - struct serial_struct __user *retinfo) +static int mos7840_get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct tmp; - - if (mos7840_port == NULL) - return -1; - - memset(&tmp, 0, sizeof(tmp)); - - tmp.type = PORT_16550A; - tmp.line = mos7840_port->port->minor; - tmp.port = mos7840_port->port->port_number; - tmp.irq = 0; - tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE; - tmp.baud_base = 9600; - tmp.close_delay = 5 * HZ; - tmp.closing_wait = 30 * HZ; + struct usb_serial_port *port = tty->driver_data; + struct moschip_port *mos7840_port = mos7840_get_port_private(port); - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; + ss->type = PORT_16550A; + ss->line = mos7840_port->port->minor; + ss->port = mos7840_port->port->port_number; + ss->irq = 0; + ss->xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE; + ss->baud_base = 9600; + ss->close_delay = 5 * HZ; + ss->closing_wait = 30 * HZ; return 0; } @@ -1982,13 +1975,6 @@ static int mos7840_ioctl(struct tty_struct *tty, dev_dbg(&port->dev, "%s TIOCSERGETLSR\n", __func__); return mos7840_get_lsr_info(tty, argp); - case TIOCGSERIAL: - dev_dbg(&port->dev, "%s TIOCGSERIAL\n", __func__); - return mos7840_get_serial_info(mos7840_port, argp); - - case TIOCSSERIAL: - dev_dbg(&port->dev, "%s TIOCSSERIAL\n", __func__); - break; default: break; } @@ -2376,6 +2362,7 @@ static struct usb_serial_driver moschip7840_4port_device = { .calc_num_ports = mos7840_calc_num_ports, .probe = mos7840_probe, .ioctl = mos7840_ioctl, + .get_serial = mos7840_get_serial_info, .set_termios = mos7840_set_termios, .break_ctl = mos7840_break, .tiocmget = mos7840_tiocmget, From 30296aa419f8caec24e31cc2e6e3e6081460e97d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 07:21:40 -0400 Subject: [PATCH 27/53] opticon: switch to ->get_serial() Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/usb/serial/opticon.c | 43 ++++++++++-------------------------- 1 file changed, 12 insertions(+), 31 deletions(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index caa0746326fd5..cb7aac9cd9e72 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -328,42 +328,23 @@ static int opticon_tiocmset(struct tty_struct *tty, return 0; } -static int get_serial_info(struct usb_serial_port *port, - struct serial_struct __user *serial) +static int get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct tmp; - - memset(&tmp, 0x00, sizeof(tmp)); + struct usb_serial_port *port = tty->driver_data; /* fake emulate a 16550 uart to make userspace code happy */ - tmp.type = PORT_16550A; - tmp.line = port->minor; - tmp.port = 0; - tmp.irq = 0; - tmp.xmit_fifo_size = 1024; - tmp.baud_base = 9600; - tmp.close_delay = 5*HZ; - tmp.closing_wait = 30*HZ; - - if (copy_to_user(serial, &tmp, sizeof(*serial))) - return -EFAULT; + ss->type = PORT_16550A; + ss->line = port->minor; + ss->port = 0; + ss->irq = 0; + ss->xmit_fifo_size = 1024; + ss->baud_base = 9600; + ss->close_delay = 5*HZ; + ss->closing_wait = 30*HZ; return 0; } -static int opticon_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - - switch (cmd) { - case TIOCGSERIAL: - return get_serial_info(port, - (struct serial_struct __user *)arg); - } - - return -ENOIOCTLCMD; -} - static int opticon_port_probe(struct usb_serial_port *port) { struct opticon_private *priv; @@ -404,7 +385,7 @@ static struct usb_serial_driver opticon_device = { .write_room = opticon_write_room, .throttle = usb_serial_generic_throttle, .unthrottle = usb_serial_generic_unthrottle, - .ioctl = opticon_ioctl, + .get_serial = get_serial_info, .tiocmget = opticon_tiocmget, .tiocmset = opticon_tiocmset, .process_read_urb = opticon_process_read_urb, From 9326ec59ec64399e031aa2fe3ab6404d24423630 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 07:23:18 -0400 Subject: [PATCH 28/53] pl2303: switch to ->get_serial() Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/usb/serial/pl2303.c | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index e41f725ac7aae..a4e0d13fc1219 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -808,29 +808,16 @@ static int pl2303_carrier_raised(struct usb_serial_port *port) return 0; } -static int pl2303_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) +static int pl2303_get_serial(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct ser; struct usb_serial_port *port = tty->driver_data; - switch (cmd) { - case TIOCGSERIAL: - memset(&ser, 0, sizeof ser); - ser.type = PORT_16654; - ser.line = port->minor; - ser.port = port->port_number; - ser.baud_base = 460800; - - if (copy_to_user((void __user *)arg, &ser, sizeof ser)) - return -EFAULT; - - return 0; - default: - break; - } - - return -ENOIOCTLCMD; + ss->type = PORT_16654; + ss->line = port->minor; + ss->port = port->port_number; + ss->baud_base = 460800; + return 0; } static void pl2303_set_break(struct usb_serial_port *port, bool enable) @@ -1016,7 +1003,7 @@ static struct usb_serial_driver pl2303_device = { .close = pl2303_close, .dtr_rts = pl2303_dtr_rts, .carrier_raised = pl2303_carrier_raised, - .ioctl = pl2303_ioctl, + .get_serial = pl2303_get_serial, .break_ctl = pl2303_break_ctl, .set_termios = pl2303_set_termios, .tiocmget = pl2303_tiocmget, From 8fbde7984e7f84aa98c6bf9eff11c6c8b72c2517 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 07:24:37 -0400 Subject: [PATCH 29/53] quatech2: switch to ->get_serial() Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/usb/serial/quatech2.c | 42 +++++++++-------------------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index b61c2a9b6b111..f2fbe1ec97017 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -453,39 +453,19 @@ static void qt2_disconnect(struct usb_serial *serial) usb_kill_urb(serial_priv->read_urb); } -static int get_serial_info(struct usb_serial_port *port, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - - memset(&tmp, 0, sizeof(tmp)); - tmp.line = port->minor; - tmp.port = 0; - tmp.irq = 0; - tmp.xmit_fifo_size = port->bulk_out_size; - tmp.baud_base = 9600; - tmp.close_delay = 5*HZ; - tmp.closing_wait = 30*HZ; - - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int qt2_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) +static int get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { struct usb_serial_port *port = tty->driver_data; - switch (cmd) { - case TIOCGSERIAL: - return get_serial_info(port, - (struct serial_struct __user *)arg); - default: - break; - } - - return -ENOIOCTLCMD; + ss->line = port->minor; + ss->port = 0; + ss->irq = 0; + ss->xmit_fifo_size = port->bulk_out_size; + ss->baud_base = 9600; + ss->close_delay = 5*HZ; + ss->closing_wait = 30*HZ; + return 0; } static void qt2_process_status(struct usb_serial_port *port, unsigned char *ch) @@ -1013,7 +993,7 @@ static struct usb_serial_driver qt2_device = { .tiocmset = qt2_tiocmset, .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, - .ioctl = qt2_ioctl, + .get_serial = get_serial_info, .set_termios = qt2_set_termios, }; From ee08cefbb5bd261676c6e7965dffd8ee2ad5e1e8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 07:26:07 -0400 Subject: [PATCH 30/53] ssu100: switch to ->get_serial() Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/usb/serial/ssu100.c | 42 ++++++++++--------------------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index 0900b47b5f57b..f6aea9f1be1a9 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c @@ -331,39 +331,19 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port) return usb_serial_generic_open(tty, port); } -static int get_serial_info(struct usb_serial_port *port, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - - memset(&tmp, 0, sizeof(tmp)); - tmp.line = port->minor; - tmp.port = 0; - tmp.irq = 0; - tmp.xmit_fifo_size = port->bulk_out_size; - tmp.baud_base = 9600; - tmp.close_delay = 5*HZ; - tmp.closing_wait = 30*HZ; - - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int ssu100_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) +static int get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { struct usb_serial_port *port = tty->driver_data; - switch (cmd) { - case TIOCGSERIAL: - return get_serial_info(port, - (struct serial_struct __user *) arg); - default: - break; - } - - return -ENOIOCTLCMD; + ss->line = port->minor; + ss->port = 0; + ss->irq = 0; + ss->xmit_fifo_size = port->bulk_out_size; + ss->baud_base = 9600; + ss->close_delay = 5*HZ; + ss->closing_wait = 30*HZ; + return 0; } static int ssu100_attach(struct usb_serial *serial) @@ -566,7 +546,7 @@ static struct usb_serial_driver ssu100_device = { .tiocmset = ssu100_tiocmset, .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, - .ioctl = ssu100_ioctl, + .get_serial = get_serial_info, .set_termios = ssu100_set_termios, }; From 57e5723611bb1598bb1cb11a5ec8a4d257f69bb3 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 07:31:12 -0400 Subject: [PATCH 31/53] ti_usb_3410_5052: switch to ->[sg]et_serial() Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/usb/serial/ti_usb_3410_5052.c | 74 +++++++++------------------ 1 file changed, 24 insertions(+), 50 deletions(-) diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 3010878f7f8ed..2657382280944 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -313,8 +313,6 @@ static int ti_chars_in_buffer(struct tty_struct *tty); static bool ti_tx_empty(struct usb_serial_port *port); static void ti_throttle(struct tty_struct *tty); static void ti_unthrottle(struct tty_struct *tty); -static int ti_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); static void ti_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios); static int ti_tiocmget(struct tty_struct *tty); @@ -330,10 +328,10 @@ static void ti_recv(struct usb_serial_port *port, unsigned char *data, static void ti_send(struct ti_port *tport); static int ti_set_mcr(struct ti_port *tport, unsigned int mcr); static int ti_get_lsr(struct ti_port *tport, u8 *lsr); -static int ti_get_serial_info(struct ti_port *tport, - struct serial_struct __user *ret_arg); -static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport, - struct serial_struct __user *new_arg); +static int ti_get_serial_info(struct tty_struct *tty, + struct serial_struct *ss); +static int ti_set_serial_info(struct tty_struct *tty, + struct serial_struct *ss); static void ti_handle_new_msr(struct ti_port *tport, u8 msr); static void ti_stop_read(struct ti_port *tport, struct tty_struct *tty); @@ -436,7 +434,8 @@ static struct usb_serial_driver ti_1port_device = { .tx_empty = ti_tx_empty, .throttle = ti_throttle, .unthrottle = ti_unthrottle, - .ioctl = ti_ioctl, + .get_serial = ti_get_serial_info, + .set_serial = ti_set_serial_info, .set_termios = ti_set_termios, .tiocmget = ti_tiocmget, .tiocmset = ti_tiocmset, @@ -469,7 +468,8 @@ static struct usb_serial_driver ti_2port_device = { .tx_empty = ti_tx_empty, .throttle = ti_throttle, .unthrottle = ti_unthrottle, - .ioctl = ti_ioctl, + .get_serial = ti_get_serial_info, + .set_serial = ti_set_serial_info, .set_termios = ti_set_termios, .tiocmget = ti_tiocmget, .tiocmset = ti_tiocmset, @@ -902,24 +902,6 @@ static void ti_unthrottle(struct tty_struct *tty) } } -static int ti_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - struct ti_port *tport = usb_get_serial_port_data(port); - - switch (cmd) { - case TIOCGSERIAL: - return ti_get_serial_info(tport, - (struct serial_struct __user *)arg); - case TIOCSSERIAL: - return ti_set_serial_info(tty, tport, - (struct serial_struct __user *)arg); - } - return -ENOIOCTLCMD; -} - - static void ti_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { @@ -1417,45 +1399,37 @@ static int ti_get_lsr(struct ti_port *tport, u8 *lsr) } -static int ti_get_serial_info(struct ti_port *tport, - struct serial_struct __user *ret_arg) +static int ti_get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { - struct usb_serial_port *port = tport->tp_port; - struct serial_struct ret_serial; + struct usb_serial_port *port = tty->driver_data; + struct ti_port *tport = usb_get_serial_port_data(port); unsigned cwait; cwait = port->port.closing_wait; if (cwait != ASYNC_CLOSING_WAIT_NONE) cwait = jiffies_to_msecs(cwait) / 10; - memset(&ret_serial, 0, sizeof(ret_serial)); - - ret_serial.type = PORT_16550A; - ret_serial.line = port->minor; - ret_serial.port = port->port_number; - ret_serial.xmit_fifo_size = kfifo_size(&port->write_fifo); - ret_serial.baud_base = tport->tp_tdev->td_is_3410 ? 921600 : 460800; - ret_serial.closing_wait = cwait; - - if (copy_to_user(ret_arg, &ret_serial, sizeof(*ret_arg))) - return -EFAULT; - + ss->type = PORT_16550A; + ss->line = port->minor; + ss->port = port->port_number; + ss->xmit_fifo_size = kfifo_size(&port->write_fifo); + ss->baud_base = tport->tp_tdev->td_is_3410 ? 921600 : 460800; + ss->closing_wait = cwait; return 0; } -static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport, - struct serial_struct __user *new_arg) +static int ti_set_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct new_serial; + struct usb_serial_port *port = tty->driver_data; + struct ti_port *tport = usb_get_serial_port_data(port); unsigned cwait; - if (copy_from_user(&new_serial, new_arg, sizeof(new_serial))) - return -EFAULT; - - cwait = new_serial.closing_wait; + cwait = ss->closing_wait; if (cwait != ASYNC_CLOSING_WAIT_NONE) - cwait = msecs_to_jiffies(10 * new_serial.closing_wait); + cwait = msecs_to_jiffies(10 * ss->closing_wait); tport->tp_port->port.closing_wait = cwait; From fc6cc979e42264efbff6c01a8c6af144cc3e43e4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 07:34:34 -0400 Subject: [PATCH 32/53] whiteheat: switch to ->get_serial() ... and fix the return value - on success it used to have ioctl(2) fill the user-supplied struct serial_struct and return -ENOTTY. Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/usb/serial/whiteheat.c | 42 ++++++++++++---------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 1c7b46a8620cc..aefd84f88b596 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -83,8 +83,8 @@ static int whiteheat_port_remove(struct usb_serial_port *port); static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port); static void whiteheat_close(struct usb_serial_port *port); -static int whiteheat_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); +static int whiteheat_get_serial(struct tty_struct *tty, + struct serial_struct *ss); static void whiteheat_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); static int whiteheat_tiocmget(struct tty_struct *tty); @@ -120,7 +120,7 @@ static struct usb_serial_driver whiteheat_device = { .port_remove = whiteheat_port_remove, .open = whiteheat_open, .close = whiteheat_close, - .ioctl = whiteheat_ioctl, + .get_serial = whiteheat_get_serial, .set_termios = whiteheat_set_termios, .break_ctl = whiteheat_break_ctl, .tiocmget = whiteheat_tiocmget, @@ -442,33 +442,21 @@ static int whiteheat_tiocmset(struct tty_struct *tty, } -static int whiteheat_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) +static int whiteheat_get_serial(struct tty_struct *tty, + struct serial_struct *ss) { struct usb_serial_port *port = tty->driver_data; - struct serial_struct serstruct; - void __user *user_arg = (void __user *)arg; - - switch (cmd) { - case TIOCGSERIAL: - memset(&serstruct, 0, sizeof(serstruct)); - serstruct.type = PORT_16654; - serstruct.line = port->minor; - serstruct.port = port->port_number; - serstruct.xmit_fifo_size = kfifo_size(&port->write_fifo); - serstruct.custom_divisor = 0; - serstruct.baud_base = 460800; - serstruct.close_delay = CLOSING_DELAY; - serstruct.closing_wait = CLOSING_DELAY; - - if (copy_to_user(user_arg, &serstruct, sizeof(serstruct))) - return -EFAULT; - break; - default: - break; - } - return -ENOIOCTLCMD; + ss->type = PORT_16654; + ss->line = port->minor; + ss->port = port->port_number; + ss->xmit_fifo_size = kfifo_size(&port->write_fifo); + ss->custom_divisor = 0; + ss->baud_base = 460800; + ss->close_delay = CLOSING_DELAY; + ss->closing_wait = CLOSING_DELAY; + + return 0; } From 15cc7bad48977582a35c06f5afa0cfc1d4975bd9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 07:45:23 -0400 Subject: [PATCH 33/53] usb_wwan: switch to ->[sg]et_serial() Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/usb/serial/option.c | 3 +- drivers/usb/serial/usb-wwan.h | 6 ++-- drivers/usb/serial/usb_wwan.c | 63 ++++++++++------------------------- 3 files changed, 23 insertions(+), 49 deletions(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 0215b70c4efc7..e6e811ac23312 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1962,7 +1962,8 @@ static struct usb_serial_driver option_1port_device = { .chars_in_buffer = usb_wwan_chars_in_buffer, .tiocmget = usb_wwan_tiocmget, .tiocmset = usb_wwan_tiocmset, - .ioctl = usb_wwan_ioctl, + .get_serial = usb_wwan_get_serial_info, + .set_serial = usb_wwan_set_serial_info, .attach = option_attach, .release = option_release, .port_probe = usb_wwan_port_probe, diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h index d28dab4b9effc..1c120eaf4091c 100644 --- a/drivers/usb/serial/usb-wwan.h +++ b/drivers/usb/serial/usb-wwan.h @@ -15,8 +15,10 @@ extern int usb_wwan_write_room(struct tty_struct *tty); extern int usb_wwan_tiocmget(struct tty_struct *tty); extern int usb_wwan_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); -extern int usb_wwan_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); +extern int usb_wwan_get_serial_info(struct tty_struct *tty, + struct serial_struct *ss); +extern int usb_wwan_set_serial_info(struct tty_struct *tty, + struct serial_struct *ss); extern int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count); extern int usb_wwan_chars_in_buffer(struct tty_struct *tty); diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 912472f26e4f6..7e855c87e4f7b 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -132,38 +132,32 @@ int usb_wwan_tiocmset(struct tty_struct *tty, } EXPORT_SYMBOL(usb_wwan_tiocmset); -static int get_serial_info(struct usb_serial_port *port, - struct serial_struct __user *retinfo) +int usb_wwan_get_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct tmp; - - memset(&tmp, 0, sizeof(tmp)); - tmp.line = port->minor; - tmp.port = port->port_number; - tmp.baud_base = tty_get_baud_rate(port->port.tty); - tmp.close_delay = port->port.close_delay / 10; - tmp.closing_wait = port->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? + struct usb_serial_port *port = tty->driver_data; + + ss->line = port->minor; + ss->port = port->port_number; + ss->baud_base = tty_get_baud_rate(port->port.tty); + ss->close_delay = port->port.close_delay / 10; + ss->closing_wait = port->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? ASYNC_CLOSING_WAIT_NONE : port->port.closing_wait / 10; - - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; return 0; } +EXPORT_SYMBOL(usb_wwan_get_serial_info); -static int set_serial_info(struct usb_serial_port *port, - struct serial_struct __user *newinfo) +int usb_wwan_set_serial_info(struct tty_struct *tty, + struct serial_struct *ss) { - struct serial_struct new_serial; + struct usb_serial_port *port = tty->driver_data; unsigned int closing_wait, close_delay; int retval = 0; - if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) - return -EFAULT; - - close_delay = new_serial.close_delay * 10; - closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? - ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10; + close_delay = ss->close_delay * 10; + closing_wait = ss->closing_wait == ASYNC_CLOSING_WAIT_NONE ? + ASYNC_CLOSING_WAIT_NONE : ss->closing_wait * 10; mutex_lock(&port->port.mutex); @@ -181,30 +175,7 @@ static int set_serial_info(struct usb_serial_port *port, mutex_unlock(&port->port.mutex); return retval; } - -int usb_wwan_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - - dev_dbg(&port->dev, "%s cmd 0x%04x\n", __func__, cmd); - - switch (cmd) { - case TIOCGSERIAL: - return get_serial_info(port, - (struct serial_struct __user *) arg); - case TIOCSSERIAL: - return set_serial_info(port, - (struct serial_struct __user *) arg); - default: - break; - } - - dev_dbg(&port->dev, "%s arg not supported\n", __func__); - - return -ENOIOCTLCMD; -} -EXPORT_SYMBOL(usb_wwan_ioctl); +EXPORT_SYMBOL(usb_wwan_set_serial_info); int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count) From 930236a30897532653a61ed22ae7eca13154accd Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 07:46:51 -0400 Subject: [PATCH 34/53] complete ->[sg]et_serial() switchover Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/tty/tty_io.c | 14 ++++---------- drivers/usb/serial/usb-serial.c | 4 ++-- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index b96bfd051d590..15d60ba131872 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2474,7 +2474,7 @@ static int tty_tiocsserial(struct tty_struct *tty, struct serial_struct __user * pr_warn("%s: '%s' is using deprecated serial flags (with no effect): %.8x\n", __func__, get_task_comm(comm, current), flags); if (!tty->ops->set_serial) - return -ENOIOCTLCMD; + return -ENOTTY; return tty->ops->set_serial(tty, &v); } @@ -2485,7 +2485,7 @@ static int tty_tiocgserial(struct tty_struct *tty, struct serial_struct __user * memset(&v, 0, sizeof(struct serial_struct)); if (!tty->ops->get_serial) - return -ENOIOCTLCMD; + return -ENOTTY; err = tty->ops->get_serial(tty, &v); if (!err && copy_to_user(ss, &v, sizeof(struct serial_struct))) err = -EFAULT; @@ -2621,15 +2621,9 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } break; case TIOCSSERIAL: - retval = tty_tiocsserial(tty, p); - if (retval != -ENOIOCTLCMD) - return retval; - break; + return tty_tiocsserial(tty, p); case TIOCGSERIAL: - retval = tty_tiocgserial(tty, p); - if (retval != -ENOIOCTLCMD) - return retval; - break; + return tty_tiocgserial(tty, p); case TIOCGPTPEER: /* Special because the struct file is needed */ return ptm_open_peer(file, tty, (int)arg); diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 0f96d82fc575c..7e89efbf2c284 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -402,7 +402,7 @@ static int serial_get_serial(struct tty_struct *tty, struct serial_struct *ss) if (port->serial->type->get_serial) return port->serial->type->get_serial(tty, ss); - return -ENOIOCTLCMD; + return -ENOTTY; } static int serial_set_serial(struct tty_struct *tty, struct serial_struct *ss) @@ -411,7 +411,7 @@ static int serial_set_serial(struct tty_struct *tty, struct serial_struct *ss) if (port->serial->type->set_serial) return port->serial->type->set_serial(tty, ss); - return -ENOIOCTLCMD; + return -ENOTTY; } static int serial_ioctl(struct tty_struct *tty, From f82fc0fedf28ba09b0abd0533202447846d48fb9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 07:49:44 -0400 Subject: [PATCH 35/53] synclink: reduce pointless checks in ->ioctl() it's never getting called with TIOC[SG]SERIAL anymore (nor has it ever supported those, while we are at it) Signed-off-by: Al Viro --- drivers/char/pcmcia/synclink_cs.c | 3 +-- drivers/tty/synclink.c | 3 +-- drivers/tty/synclink_gt.c | 3 +-- drivers/tty/synclinkmp.c | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 66b04194aa9f8..82f9a6a814ae8 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -2237,8 +2237,7 @@ static int mgslpc_ioctl(struct tty_struct *tty, if (mgslpc_paranoia_check(info, tty->name, "mgslpc_ioctl")) return -ENODEV; - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCMIWAIT)) { + if (cmd != TIOCMIWAIT) { if (tty_io_error(tty)) return -EIO; } diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index fbdf4d01c6a9c..d55c858d6058b 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c @@ -2959,8 +2959,7 @@ static int mgsl_ioctl(struct tty_struct *tty, if (mgsl_paranoia_check(info, tty->name, "mgsl_ioctl")) return -ENODEV; - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCMIWAIT)) { + if (cmd != TIOCMIWAIT) { if (tty_io_error(tty)) return -EIO; } diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index a94086597ebd6..b8287a0103365 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -1029,8 +1029,7 @@ static int ioctl(struct tty_struct *tty, return -ENODEV; DBGINFO(("%s ioctl() cmd=%08X\n", info->device_name, cmd)); - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCMIWAIT)) { + if (cmd != TIOCMIWAIT) { if (tty_io_error(tty)) return -EIO; } diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index 1e4d5b9c981a4..fcb91bf7a15ba 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c @@ -1259,8 +1259,7 @@ static int ioctl(struct tty_struct *tty, if (sanity_check(info, tty->name, "ioctl")) return -ENODEV; - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCMIWAIT)) { + if (cmd != TIOCMIWAIT) { if (tty_io_error(tty)) return -EIO; } From 77654350306accb55efa73eaa2b1424a639595fc Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 11:28:34 -0400 Subject: [PATCH 36/53] take compat TIOC[SG]SERIAL treatment into tty_compat_ioctl() Signed-off-by: Al Viro --- drivers/tty/tty_io.c | 81 ++++++++++++++++++++++++++++++++++++++++++++ fs/compat_ioctl.c | 67 ------------------------------------ 2 files changed, 81 insertions(+), 67 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 15d60ba131872..ccc0055b2dfcb 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2651,6 +2651,81 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } #ifdef CONFIG_COMPAT + +struct serial_struct32 { + compat_int_t type; + compat_int_t line; + compat_uint_t port; + compat_int_t irq; + compat_int_t flags; + compat_int_t xmit_fifo_size; + compat_int_t custom_divisor; + compat_int_t baud_base; + unsigned short close_delay; + char io_type; + char reserved_char[1]; + compat_int_t hub6; + unsigned short closing_wait; /* time to wait before closing */ + unsigned short closing_wait2; /* no longer used... */ + compat_uint_t iomem_base; + unsigned short iomem_reg_shift; + unsigned int port_high; + /* compat_ulong_t iomap_base FIXME */ + compat_int_t reserved[1]; +}; + +static int compat_tty_tiocsserial(struct tty_struct *tty, + struct serial_struct32 __user *ss) +{ + static DEFINE_RATELIMIT_STATE(depr_flags, + DEFAULT_RATELIMIT_INTERVAL, + DEFAULT_RATELIMIT_BURST); + char comm[TASK_COMM_LEN]; + struct serial_struct32 v32; + struct serial_struct v; + int flags; + + if (copy_from_user(&v32, ss, sizeof(struct serial_struct32))) + return -EFAULT; + + memcpy(&v, &v32, offsetof(struct serial_struct32, iomem_base)); + v.iomem_base = compat_ptr(v32.iomem_base); + v.iomem_reg_shift = v32.iomem_reg_shift; + v.port_high = v32.port_high; + v.iomap_base = 0; + + flags = v.flags & ASYNC_DEPRECATED; + + if (flags && __ratelimit(&depr_flags)) + pr_warn("%s: '%s' is using deprecated serial flags (with no effect): %.8x\n", + __func__, get_task_comm(comm, current), flags); + if (!tty->ops->set_serial) + return -ENOTTY; + return tty->ops->set_serial(tty, &v); +} + +static int compat_tty_tiocgserial(struct tty_struct *tty, + struct serial_struct32 __user *ss) +{ + struct serial_struct32 v32; + struct serial_struct v; + int err; + memset(&v, 0, sizeof(struct serial_struct)); + + if (!tty->ops->set_serial) + return -ENOTTY; + err = tty->ops->get_serial(tty, &v); + if (!err) { + memcpy(&v32, &v, offsetof(struct serial_struct32, iomem_base)); + v32.iomem_base = (unsigned long)v.iomem_base >> 32 ? + 0xfffffff : ptr_to_compat(v.iomem_base); + v32.iomem_reg_shift = v.iomem_reg_shift; + v32.port_high = v.port_high; + if (copy_to_user(ss, &v32, sizeof(struct serial_struct32))) + err = -EFAULT; + } + return err; +} static long tty_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -2736,6 +2811,12 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, if (tty_paranoia_check(tty, file_inode(file), "tty_ioctl")) return -EINVAL; + switch (cmd) { + case TIOCSSERIAL: + return compat_tty_tiocsserial(tty, compat_ptr(arg)); + case TIOCGSERIAL: + return compat_tty_tiocgserial(tty, compat_ptr(arg)); + } if (tty->ops->compat_ioctl) { retval = tty->ops->compat_ioctl(tty, cmd, arg); if (retval != -ENOIOCTLCMD) diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 670b8cbd08966..2b35c6707e3df 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -560,69 +560,6 @@ static int mt_ioctl_trans(struct file *file, #define HIDPGETCONNLIST _IOR('H', 210, int) #define HIDPGETCONNINFO _IOR('H', 211, int) - -struct serial_struct32 { - compat_int_t type; - compat_int_t line; - compat_uint_t port; - compat_int_t irq; - compat_int_t flags; - compat_int_t xmit_fifo_size; - compat_int_t custom_divisor; - compat_int_t baud_base; - unsigned short close_delay; - char io_type; - char reserved_char[1]; - compat_int_t hub6; - unsigned short closing_wait; /* time to wait before closing */ - unsigned short closing_wait2; /* no longer used... */ - compat_uint_t iomem_base; - unsigned short iomem_reg_shift; - unsigned int port_high; - /* compat_ulong_t iomap_base FIXME */ - compat_int_t reserved[1]; -}; - -static int serial_struct_ioctl(struct file *file, - unsigned cmd, struct serial_struct32 __user *ss32) -{ - typedef struct serial_struct32 SS32; - int err; - struct serial_struct __user *ss = compat_alloc_user_space(sizeof(*ss)); - __u32 udata; - unsigned int base; - unsigned char *iomem_base; - - if (ss == NULL) - return -EFAULT; - if (cmd == TIOCSSERIAL) { - if (copy_in_user(ss, ss32, offsetof(SS32, iomem_base)) || - get_user(udata, &ss32->iomem_base)) - return -EFAULT; - iomem_base = compat_ptr(udata); - if (put_user(iomem_base, &ss->iomem_base) || - convert_in_user(&ss32->iomem_reg_shift, - &ss->iomem_reg_shift) || - convert_in_user(&ss32->port_high, &ss->port_high) || - put_user(0UL, &ss->iomap_base)) - return -EFAULT; - } - err = do_ioctl(file, cmd, (unsigned long)ss); - if (cmd == TIOCGSERIAL && err >= 0) { - if (copy_in_user(ss32, ss, offsetof(SS32, iomem_base)) || - get_user(iomem_base, &ss->iomem_base)) - return -EFAULT; - base = (unsigned long)iomem_base >> 32 ? - 0xffffffff : (unsigned)(unsigned long)iomem_base; - if (put_user(base, &ss32->iomem_base) || - convert_in_user(&ss->iomem_reg_shift, - &ss32->iomem_reg_shift) || - convert_in_user(&ss->port_high, &ss32->port_high)) - return -EFAULT; - } - return err; -} - #define RTC_IRQP_READ32 _IOR('p', 0x0b, compat_ulong_t) #define RTC_IRQP_SET32 _IOW('p', 0x0c, compat_ulong_t) #define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t) @@ -1242,10 +1179,6 @@ static long do_ioctl_trans(unsigned int cmd, case MTIOCPOS32: return mt_ioctl_trans(file, cmd, argp); #endif - /* Serial */ - case TIOCGSERIAL: - case TIOCSSERIAL: - return serial_struct_ioctl(file, cmd, argp); /* Not implemented in the native kernel */ case RTC_IRQP_READ32: case RTC_IRQP_SET32: From 864e880de59ecd891260f264d2884eabb9d6760c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 17:52:23 -0400 Subject: [PATCH 37/53] kill capinc_tty_ioctl() NULL ->ioctl() in tty_operations is treated as "returns -ENOIOCTLCMD"... Signed-off-by: Al Viro --- drivers/isdn/capi/capi.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index ef5560b848ab3..e1da70a9530c8 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1155,12 +1155,6 @@ static int capinc_tty_chars_in_buffer(struct tty_struct *tty) return mp->outbytes; } -static int capinc_tty_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - return -ENOIOCTLCMD; -} - static void capinc_tty_set_termios(struct tty_struct *tty, struct ktermios *old) { pr_debug("capinc_tty_set_termios\n"); @@ -1236,7 +1230,6 @@ static const struct tty_operations capinc_ops = { .flush_chars = capinc_tty_flush_chars, .write_room = capinc_tty_write_room, .chars_in_buffer = capinc_tty_chars_in_buffer, - .ioctl = capinc_tty_ioctl, .set_termios = capinc_tty_set_termios, .throttle = capinc_tty_throttle, .unthrottle = capinc_tty_unthrottle, From e67504c5958f122944d4b9316d1cfc737027c466 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 17:54:22 -0400 Subject: [PATCH 38/53] isdn_tty: TCSBRK{,P} won't reach ->ioctl() kill the long-dead code - it's been unreachable since 2008. Redundant, as well - generic will do exact same thing, since ->break_ctl is NULL here... Signed-off-by: Al Viro --- drivers/isdn/i4l/isdn_tty.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index b730037a0e2d3..1b2239c1d5694 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -1412,31 +1412,12 @@ static int isdn_tty_ioctl(struct tty_struct *tty, uint cmd, ulong arg) { modem_info *info = (modem_info *) tty->driver_data; - int retval; if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_ioctl")) return -ENODEV; if (tty_io_error(tty)) return -EIO; switch (cmd) { - case TCSBRK: /* SVID version: non-zero arg --> no break */ -#ifdef ISDN_DEBUG_MODEM_IOCTL - printk(KERN_DEBUG "ttyI%d ioctl TCSBRK\n", info->line); -#endif - retval = tty_check_change(tty); - if (retval) - return retval; - tty_wait_until_sent(tty, 0); - return 0; - case TCSBRKP: /* support for POSIX tcsendbreak() */ -#ifdef ISDN_DEBUG_MODEM_IOCTL - printk(KERN_DEBUG "ttyI%d ioctl TCSBRKP\n", info->line); -#endif - retval = tty_check_change(tty); - if (retval) - return retval; - tty_wait_until_sent(tty, 0); - return 0; case TIOCSERGETLSR: /* Get line status register */ #ifdef ISDN_DEBUG_MODEM_IOCTL printk(KERN_DEBUG "ttyI%d ioctl TIOCSERGETLSR\n", info->line); From 04ec1c8c7411d4bbb80d7ac93e93b2a5d2824842 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 18:00:47 -0400 Subject: [PATCH 39/53] dgnc: TIOCM... won't reach ->ioctl() bury the dead code (and ->tiocmget()/->tiocmset() are there, so I really wonder why have they kept the stuff that became unreachable with the introduction of those...) Signed-off-by: Al Viro --- drivers/staging/dgnc/dgnc_tty.c | 114 -------------------------------- 1 file changed, 114 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index f91eaa1c3b67d..9accaa7058201 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -60,10 +60,6 @@ static void dgnc_tty_unthrottle(struct tty_struct *tty); static void dgnc_tty_flush_chars(struct tty_struct *tty); static void dgnc_tty_flush_buffer(struct tty_struct *tty); static void dgnc_tty_hangup(struct tty_struct *tty); -static int dgnc_set_modem_info(struct channel_t *ch, unsigned int command, - unsigned int __user *value); -static int dgnc_get_modem_info(struct channel_t *ch, - unsigned int __user *value); static int dgnc_tty_tiocmget(struct tty_struct *tty); static int dgnc_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); @@ -1701,106 +1697,6 @@ static void dgnc_tty_send_xchar(struct tty_struct *tty, char c) spin_unlock_irqrestore(&ch->ch_lock, flags); } -/* Return modem signals to ld. */ -static inline int dgnc_get_mstat(struct channel_t *ch) -{ - unsigned char mstat; - unsigned long flags; - int rc; - - if (!ch) - return -ENXIO; - - spin_lock_irqsave(&ch->ch_lock, flags); - - mstat = ch->ch_mostat | ch->ch_mistat; - - spin_unlock_irqrestore(&ch->ch_lock, flags); - - rc = 0; - - if (mstat & UART_MCR_DTR) - rc |= TIOCM_DTR; - if (mstat & UART_MCR_RTS) - rc |= TIOCM_RTS; - if (mstat & UART_MSR_CTS) - rc |= TIOCM_CTS; - if (mstat & UART_MSR_DSR) - rc |= TIOCM_DSR; - if (mstat & UART_MSR_RI) - rc |= TIOCM_RI; - if (mstat & UART_MSR_DCD) - rc |= TIOCM_CD; - - return rc; -} - -/* Return modem signals to ld. */ -static int dgnc_get_modem_info(struct channel_t *ch, - unsigned int __user *value) -{ - return put_user(dgnc_get_mstat(ch), value); -} - -/* Set modem signals, called by ld. */ -static int dgnc_set_modem_info(struct channel_t *ch, - unsigned int command, - unsigned int __user *value) -{ - int rc; - unsigned int arg = 0; - unsigned long flags; - - rc = get_user(arg, value); - if (rc) - return rc; - - switch (command) { - case TIOCMBIS: - if (arg & TIOCM_RTS) - ch->ch_mostat |= UART_MCR_RTS; - - if (arg & TIOCM_DTR) - ch->ch_mostat |= UART_MCR_DTR; - - break; - - case TIOCMBIC: - if (arg & TIOCM_RTS) - ch->ch_mostat &= ~(UART_MCR_RTS); - - if (arg & TIOCM_DTR) - ch->ch_mostat &= ~(UART_MCR_DTR); - - break; - - case TIOCMSET: - - if (arg & TIOCM_RTS) - ch->ch_mostat |= UART_MCR_RTS; - else - ch->ch_mostat &= ~(UART_MCR_RTS); - - if (arg & TIOCM_DTR) - ch->ch_mostat |= UART_MCR_DTR; - else - ch->ch_mostat &= ~(UART_MCR_DTR); - - break; - - default: - return -EINVAL; - } - - spin_lock_irqsave(&ch->ch_lock, flags); - - ch->ch_bd->bd_ops->assert_modem_signals(ch); - - spin_unlock_irqrestore(&ch->ch_lock, flags); - - return 0; -} - /* Ioctl to get the information for ditty. */ static int dgnc_tty_digigeta(struct tty_struct *tty, struct digi_t __user *retinfo) @@ -2282,16 +2178,6 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, return 0; - case TIOCMGET: - spin_unlock_irqrestore(&ch->ch_lock, flags); - return dgnc_get_modem_info(ch, uarg); - - case TIOCMBIS: - case TIOCMBIC: - case TIOCMSET: - spin_unlock_irqrestore(&ch->ch_lock, flags); - return dgnc_set_modem_info(ch, cmd, uarg); - /* Here are any additional ioctl's that we want to implement */ case TCFLSH: From 6bbf265892241f540d3465c074c04a39b7f127ec Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 18:05:07 -0400 Subject: [PATCH 40/53] kill the rest of tty COMPAT_IOCTL() entries TIOCLINUX is handled by ->compat_ioctl() in the only place that has native ->ioctl() recognizing it, TIOC{START,STOP} are simply useless these days - unrecognized compat ioctl won't spew into syslog anymore. Signed-off-by: Al Viro --- fs/compat_ioctl.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 2b35c6707e3df..ca2b51d9cb61e 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -647,8 +647,6 @@ static unsigned int ioctl_pointer[] = { COMPATIBLE_IOCTL(0x4B50) /* KDGHWCLK - not in the kernel, but don't complain */ COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain */ -/* Big T */ -COMPATIBLE_IOCTL(TIOCLINUX) /* Little t */ COMPATIBLE_IOCTL(TIOCOUTQ) /* Little f */ @@ -1113,17 +1111,6 @@ COMPATIBLE_IOCTL(JSIOCGAXES) COMPATIBLE_IOCTL(JSIOCGBUTTONS) COMPATIBLE_IOCTL(JSIOCGNAME(0)) -#ifdef TIOCSTART -/* - * For these two we have definitions in ioctls.h and/or termios.h on - * some architectures but no actual implemention. Some applications - * like bash call them if they are defined in the headers, so we provide - * entries here to avoid syslog message spew. - */ -COMPATIBLE_IOCTL(TIOCSTART) -COMPATIBLE_IOCTL(TIOCSTOP) -#endif - /* fat 'r' ioctls. These are handled by fat with ->compat_ioctl, but we don't want warnings on other file systems. So declare them as compatible here. */ From b413f00ab1a99ccb239fc5afd4b8e0c7ada6c9db Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 18:32:47 -0400 Subject: [PATCH 41/53] dgnc: break-related ioctls won't reach ->ioctl() kill the dead code, especially since ->break_ctl() will do the right thing anyway. Signed-off-by: Al Viro --- drivers/staging/dgnc/dgnc_tty.c | 75 --------------------------------- 1 file changed, 75 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 9accaa7058201..040af55e9e68c 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -2081,81 +2081,6 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, switch (cmd) { /* Here are all the standard ioctl's that we MUST implement */ - - case TCSBRK: - /* - * TCSBRK is SVID version: non-zero arg --> no break - * this behaviour is exploited by tcdrain(). - * - * According to POSIX.1 spec (7.2.2.1.2) breaks should be - * between 0.25 and 0.5 seconds so we'll ask for something - * in the middle: 0.375 seconds. - */ - rc = tty_check_change(tty); - spin_unlock_irqrestore(&ch->ch_lock, flags); - if (rc) - return rc; - - rc = ch_bd_ops->drain(tty, 0); - if (rc) - return -EINTR; - - spin_lock_irqsave(&ch->ch_lock, flags); - - if (((cmd == TCSBRK) && (!arg)) || (cmd == TCSBRKP)) - ch_bd_ops->send_break(ch, 250); - - spin_unlock_irqrestore(&ch->ch_lock, flags); - - return 0; - - case TCSBRKP: - /* - * support for POSIX tcsendbreak() - * According to POSIX.1 spec (7.2.2.1.2) breaks should be - * between 0.25 and 0.5 seconds so we'll ask for something - * in the middle: 0.375 seconds. - */ - rc = tty_check_change(tty); - spin_unlock_irqrestore(&ch->ch_lock, flags); - if (rc) - return rc; - - rc = ch_bd_ops->drain(tty, 0); - if (rc) - return -EINTR; - - spin_lock_irqsave(&ch->ch_lock, flags); - - ch_bd_ops->send_break(ch, 250); - - spin_unlock_irqrestore(&ch->ch_lock, flags); - - return 0; - - case TIOCSBRK: - rc = tty_check_change(tty); - spin_unlock_irqrestore(&ch->ch_lock, flags); - if (rc) - return rc; - - rc = ch_bd_ops->drain(tty, 0); - if (rc) - return -EINTR; - - spin_lock_irqsave(&ch->ch_lock, flags); - - ch_bd_ops->send_break(ch, 250); - - spin_unlock_irqrestore(&ch->ch_lock, flags); - - return 0; - - case TIOCCBRK: - /* Do Nothing */ - spin_unlock_irqrestore(&ch->ch_lock, flags); - return 0; - case TIOCGSOFTCAR: spin_unlock_irqrestore(&ch->ch_lock, flags); From a3096199226c2e4dc019f21c1bed6e96092d4a71 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 18:37:18 -0400 Subject: [PATCH 42/53] remove fallback to drivers for TIOCGICOUNT none of them handles it anyway. Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- drivers/tty/tty_io.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index ccc0055b2dfcb..1a55c3e202992 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2606,11 +2606,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case TIOCMBIS: return tty_tiocmset(tty, cmd, p); case TIOCGICOUNT: - retval = tty_tiocgicount(tty, p); - /* For the moment allow fall through to the old method */ - if (retval != -EINVAL) - return retval; - break; + return tty_tiocgicount(tty, p); case TCFLSH: switch (arg) { case TCIFLUSH: From 88d50890b78f68ff047e4deee651ec4e256cefea Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 18:40:04 -0400 Subject: [PATCH 43/53] dgnc: leave TIOC[GS]SOFTCAR to ldisc no point duplicating that in tty_operations ->ioctl() Signed-off-by: Al Viro --- drivers/staging/dgnc/dgnc_tty.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 040af55e9e68c..c01616f9e6094 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -2080,31 +2080,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, } switch (cmd) { - /* Here are all the standard ioctl's that we MUST implement */ - case TIOCGSOFTCAR: - - spin_unlock_irqrestore(&ch->ch_lock, flags); - - return put_user(C_CLOCAL(tty) ? 1 : 0, - (unsigned long __user *)arg); - - case TIOCSSOFTCAR: - - spin_unlock_irqrestore(&ch->ch_lock, flags); - rc = get_user(arg, (unsigned long __user *)arg); - if (rc) - return rc; - - spin_lock_irqsave(&ch->ch_lock, flags); - tty->termios.c_cflag = ((tty->termios.c_cflag & ~CLOCAL) | - (arg ? CLOCAL : 0)); - ch_bd_ops->param(tty); - spin_unlock_irqrestore(&ch->ch_lock, flags); - - return 0; - /* Here are any additional ioctl's that we want to implement */ - case TCFLSH: /* * The linux tty driver doesn't have a flush From 7ebec8d235419a92af42b2d20e0d6cb6dac07dd8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 18:41:46 -0400 Subject: [PATCH 44/53] dgnc: don't bother with (empty) stub for TCXONC for pity sake, that case is identical to their default: _and_ bears an explicit comment re leaving to ldisc. Which is what default is doing, obviously... Signed-off-by: Al Viro --- drivers/staging/dgnc/dgnc_tty.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index c01616f9e6094..b8f8650189509 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -2157,11 +2157,6 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, /* pretend we didn't recognize this */ return -ENOIOCTLCMD; - case TCXONC: - spin_unlock_irqrestore(&ch->ch_lock, flags); - /* Make the ld do it */ - return -ENOIOCTLCMD; - case DIGI_GETA: /* get information for ditty */ spin_unlock_irqrestore(&ch->ch_lock, flags); From 09d88c85769262aadc85a49d6d4e91d35c115db1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 18:45:29 -0400 Subject: [PATCH 45/53] gigaset: don't try to printk userland buffer contents especially when you've just copied it in... Signed-off-by: Al Viro --- drivers/isdn/gigaset/interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 600c79b030cdb..f9698c0c3885f 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -206,7 +206,7 @@ static int if_ioctl(struct tty_struct *tty, ? -EFAULT : 0; if (retval >= 0) { gigaset_dbg_buffer(DEBUG_IF, "GIGASET_BRKCHARS", - 6, (const unsigned char *) arg); + 6, buf); retval = cs->ops->brkchars(cs, buf); } break; From 9d1807daefc00c7b3a4ecca02e3a783263c1e00d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 19:02:10 -0400 Subject: [PATCH 46/53] vt_compat_ioctl(): clean up, use compat_ptr() properly we need it for "convert the structure" cases too Signed-off-by: Al Viro --- drivers/tty/vt/vt_ioctl.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index a78ad10a119b5..82d38d7ba0146 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -1171,17 +1171,13 @@ long vt_compat_ioctl(struct tty_struct *tty, { struct vc_data *vc = tty->driver_data; struct console_font_op op; /* used in multiple places here */ - unsigned int console; - void __user *up = (void __user *)arg; + unsigned int console = vc->vc_num; + void __user *up = compat_ptr(arg); int perm; - int ret = 0; - console = vc->vc_num; - if (!vc_cons_allocated(console)) { /* impossible? */ - ret = -ENOIOCTLCMD; - goto out; - } + if (!vc_cons_allocated(console)) /* impossible? */ + return -ENOIOCTLCMD; /* * To have permissions to do most of the vt ioctls, we either have @@ -1197,17 +1193,14 @@ long vt_compat_ioctl(struct tty_struct *tty, */ case PIO_FONTX: case GIO_FONTX: - ret = compat_fontx_ioctl(cmd, up, perm, &op); - break; + return compat_fontx_ioctl(cmd, up, perm, &op); case KDFONTOP: - ret = compat_kdfontop_ioctl(up, perm, &op, vc); - break; + return compat_kdfontop_ioctl(up, perm, &op, vc); case PIO_UNIMAP: case GIO_UNIMAP: - ret = compat_unimap_ioctl(cmd, up, perm, vc); - break; + return compat_unimap_ioctl(cmd, up, perm, vc); /* * all these treat 'arg' as an integer @@ -1232,21 +1225,15 @@ long vt_compat_ioctl(struct tty_struct *tty, case VT_DISALLOCATE: case VT_RESIZE: case VT_RESIZEX: - goto fallback; + return vt_ioctl(tty, cmd, arg); /* * the rest has a compatible data structure behind arg, * but we have to convert it to a proper 64 bit pointer. */ default: - arg = (unsigned long)compat_ptr(arg); - goto fallback; + return vt_ioctl(tty, cmd, (unsigned long)up); } -out: - return ret; - -fallback: - return vt_ioctl(tty, cmd, arg); } From 969ec01e992009200ecf7ba760f9fe8a95abf32a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 20:02:50 -0400 Subject: [PATCH 47/53] gigaset: add ->compat_ioctl() ... and get rid of COMPAT_IOCTL() for its private ioctls Signed-off-by: Al Viro --- drivers/isdn/gigaset/interface.c | 11 +++++++++++ fs/compat_ioctl.c | 5 ----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index f9698c0c3885f..d9a578ac32cd0 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -233,6 +233,14 @@ static int if_ioctl(struct tty_struct *tty, return retval; } +#ifdef CONFIG_COMPAT +static long if_compat_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + return if_ioctl(tty, cmd, (unsigned long)compat_ptr(arg)); +} +#endif + static int if_tiocmget(struct tty_struct *tty) { struct cardstate *cs = tty->driver_data; @@ -472,6 +480,9 @@ static const struct tty_operations if_ops = { .open = if_open, .close = if_close, .ioctl = if_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = if_compat_ioctl, +#endif .write = if_write, .write_room = if_write_room, .chars_in_buffer = if_chars_in_buffer, diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index ca2b51d9cb61e..7eec04b6e7577 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -1021,11 +1021,6 @@ COMPATIBLE_IOCTL(CAPI_SET_FLAGS) COMPATIBLE_IOCTL(CAPI_CLR_FLAGS) COMPATIBLE_IOCTL(CAPI_NCCI_OPENCOUNT) COMPATIBLE_IOCTL(CAPI_NCCI_GETUNIT) -/* Siemens Gigaset */ -COMPATIBLE_IOCTL(GIGASET_REDIR) -COMPATIBLE_IOCTL(GIGASET_CONFIG) -COMPATIBLE_IOCTL(GIGASET_BRKCHARS) -COMPATIBLE_IOCTL(GIGASET_VERSION) /* Misc. */ COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */ COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */ From 82a6857bf9efa8f66e2476f248021c17cd423159 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 20:18:09 -0400 Subject: [PATCH 48/53] compat_ioctl - kill keyboard ioctl handling all of those are provided only by vt and s390 tty3270; both have proper ->compat_ioctl() Signed-off-by: Al Viro --- fs/compat_ioctl.c | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 7eec04b6e7577..0c445a03e682c 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -644,9 +644,6 @@ static int compat_ioctl_preallocate(struct file *file, static unsigned int ioctl_pointer[] = { /* compatible ioctls first */ -COMPATIBLE_IOCTL(0x4B50) /* KDGHWCLK - not in the kernel, but don't complain */ -COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain */ - /* Little t */ COMPATIBLE_IOCTL(TIOCOUTQ) /* Little f */ @@ -663,23 +660,6 @@ COMPATIBLE_IOCTL(FIGETBSZ) COMPATIBLE_IOCTL(FIFREEZE) COMPATIBLE_IOCTL(FITHAW) COMPATIBLE_IOCTL(FITRIM) -COMPATIBLE_IOCTL(KDGETKEYCODE) -COMPATIBLE_IOCTL(KDSETKEYCODE) -COMPATIBLE_IOCTL(KDGKBTYPE) -COMPATIBLE_IOCTL(KDGETMODE) -COMPATIBLE_IOCTL(KDGKBMODE) -COMPATIBLE_IOCTL(KDGKBMETA) -COMPATIBLE_IOCTL(KDGKBENT) -COMPATIBLE_IOCTL(KDSKBENT) -COMPATIBLE_IOCTL(KDGKBSENT) -COMPATIBLE_IOCTL(KDSKBSENT) -COMPATIBLE_IOCTL(KDGKBDIACR) -COMPATIBLE_IOCTL(KDSKBDIACR) -COMPATIBLE_IOCTL(KDGKBDIACRUC) -COMPATIBLE_IOCTL(KDSKBDIACRUC) -COMPATIBLE_IOCTL(KDKBDREP) -COMPATIBLE_IOCTL(KDGKBLED) -COMPATIBLE_IOCTL(KDGETLED) #ifdef CONFIG_BLOCK /* Big S */ COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN) @@ -1185,15 +1165,6 @@ static long do_ioctl_trans(unsigned int cmd, case HOT_ADD_DISK: case SET_DISK_FAULTY: case SET_BITMAP_FILE: - /* Big K */ - case KDSIGACCEPT: - case KIOCSOUND: - case KDMKTONE: - case KDSETMODE: - case KDSKBMODE: - case KDSKBMETA: - case KDSKBLED: - case KDSETLED: return vfs_ioctl(file, cmd, arg); } From 50f45326afab723df529eca54095e2feac24da2d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 20:53:46 -0400 Subject: [PATCH 49/53] pty: fix compat ioctls pointer-taking ones need compat_ptr(); int-taking one doesn't. Signed-off-by: Al Viro --- drivers/tty/pty.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 678406e0948b2..00099a8439d21 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -28,6 +28,7 @@ #include #include #include +#include #undef TTY_DEBUG_HANGUP #ifdef TTY_DEBUG_HANGUP @@ -488,6 +489,7 @@ static int pty_bsd_ioctl(struct tty_struct *tty, return -ENOIOCTLCMD; } +#ifdef CONFIG_COMPAT static long pty_bsd_compat_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { @@ -495,8 +497,11 @@ static long pty_bsd_compat_ioctl(struct tty_struct *tty, * PTY ioctls don't require any special translation between 32-bit and * 64-bit userspace, they are already compatible. */ - return pty_bsd_ioctl(tty, cmd, arg); + return pty_bsd_ioctl(tty, cmd, (unsigned long)compat_ptr(arg)); } +#else +#define pty_bsd_compat_ioctl NULL +#endif static int legacy_count = CONFIG_LEGACY_PTY_COUNT; /* @@ -676,6 +681,7 @@ static int pty_unix98_ioctl(struct tty_struct *tty, return -ENOIOCTLCMD; } +#ifdef CONFIG_COMPAT static long pty_unix98_compat_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { @@ -683,8 +689,12 @@ static long pty_unix98_compat_ioctl(struct tty_struct *tty, * PTY ioctls don't require any special translation between 32-bit and * 64-bit userspace, they are already compatible. */ - return pty_unix98_ioctl(tty, cmd, arg); + return pty_unix98_ioctl(tty, cmd, + cmd == TIOCSIG ? arg : (unsigned long)compat_ptr(arg)); } +#else +#define pty_unix98_compat_ioctl NULL +#endif /** * ptm_unix98_lookup - find a pty master From 27230e51349fde075598c1b59d15e1ff802f3f6e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 12 Sep 2018 20:57:18 -0400 Subject: [PATCH 50/53] synclink_gt(): fix compat_ioctl() compat_ptr() for pointer-taking ones... Signed-off-by: Al Viro --- drivers/tty/synclink_gt.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index b8287a0103365..e8a9047de4516 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -1185,14 +1185,13 @@ static long slgt_compat_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct slgt_info *info = tty->driver_data; - int rc = -ENOIOCTLCMD; + int rc; if (sanity_check(info, tty->name, "compat_ioctl")) return -ENODEV; DBGINFO(("%s compat_ioctl() cmd=%08X\n", info->device_name, cmd)); switch (cmd) { - case MGSL_IOCSPARAMS32: rc = set_params32(info, compat_ptr(arg)); break; @@ -1212,18 +1211,11 @@ static long slgt_compat_ioctl(struct tty_struct *tty, case MGSL_IOCWAITGPIO: case MGSL_IOCGXSYNC: case MGSL_IOCGXCTRL: - case MGSL_IOCSTXIDLE: - case MGSL_IOCTXENABLE: - case MGSL_IOCRXENABLE: - case MGSL_IOCTXABORT: - case TIOCMIWAIT: - case MGSL_IOCSIF: - case MGSL_IOCSXSYNC: - case MGSL_IOCSXCTRL: - rc = ioctl(tty, cmd, arg); + rc = ioctl(tty, cmd, (unsigned long)compat_ptr(arg)); break; + default: + rc = ioctl(tty, cmd, arg); } - DBGINFO(("%s compat_ioctl() cmd=%08X rc=%d\n", info->device_name, cmd, rc)); return rc; } From 7ee329655189f32f0c17e0bad60c23a69b003e9e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 13 Sep 2018 16:39:58 -0400 Subject: [PATCH 51/53] kill TIOCSER[SG]WILD the only user is very old setserial rc script and even that (as far back as MCC Interim, AFAICS) doesn't actually fail - just gives one message during the boot ("Cannot scan for wild interrupts") and proceeds past that just fine. Signed-off-by: Al Viro --- arch/ia64/hp/sim/simserial.c | 5 ----- drivers/tty/amiserial.c | 6 ------ drivers/tty/serial/serial_core.c | 5 ----- 3 files changed, 16 deletions(-) diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index de5e69162ad53..759a3bbec1838 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -322,11 +322,6 @@ static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) case TIOCSERCONFIG: case TIOCSERGETLSR: /* Get line status register */ return -EINVAL; - case TIOCSERGWILD: - case TIOCSERSWILD: - /* "setserial -W" is called in Debian boot */ - printk (KERN_INFO "TIOCSER?WILD ioctl obsolete, ignored.\n"); - return 0; } return -ENOIOCTLCMD; } diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 51cfe4f1afcfd..6992adf826f4a 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1274,12 +1274,6 @@ static int rs_ioctl(struct tty_struct *tty, finish_wait(&info->tport.delta_msr_wait, &wait); return ret; - case TIOCSERGWILD: - case TIOCSERSWILD: - /* "setserial -W" is called in Debian boot */ - printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); - return 0; - default: return -ENOIOCTLCMD; } diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 2c8162b8ebf2c..54726c3f74c62 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1324,11 +1324,6 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) ret = uart_do_autoconfig(tty, state); up_write(&tty->termios_rwsem); break; - - case TIOCSERGWILD: /* obsolete */ - case TIOCSERSWILD: /* obsolete */ - ret = 0; - break; } if (ret != -ENOIOCTLCMD) From f0193d3ea73b966b5dbfa272c8228d743b8856ef Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 13 Sep 2018 22:12:15 -0400 Subject: [PATCH 52/53] change semantics of ldisc ->compat_ioctl() First of all, make it return int. Returning long when native method had never allowed that is ridiculous and inconvenient. More importantly, change the caller; if ldisc ->compat_ioctl() is NULL or returns -ENOIOCTLCMD, tty_compat_ioctl() will try to feed cmd and compat_ptr(arg) to ldisc's native ->ioctl(). That simplifies ->compat_ioctl() instances quite a bit - they only need to deal with ioctls that are neither generic tty ones (those would get shunted off to tty_ioctl()) nor simple compat pointer ones. Note that something like TCFLSH won't reach ->compat_ioctl(), even if ldisc ->ioctl() does handle it - it will be recognized earlier and passed to tty_ioctl() (and ultimately - ldisc ->ioctl()). For many ldiscs it means that NULL ->compat_ioctl() does the right thing. Those where it won't serve (see e.g. n_r3964.c) are also easily dealt with - we need to handle the numeric-argument ioctls (calling the native instance) and, if such would exist, the ioctls that need layout conversion, etc. All in-tree ldiscs dealt with. Signed-off-by: Al Viro --- drivers/bluetooth/hci_ldisc.c | 1 + drivers/input/serio/serport.c | 2 +- drivers/net/hamradio/6pack.c | 21 --------------------- drivers/net/hamradio/mkiss.c | 21 --------------------- drivers/net/slip/slip.c | 25 ------------------------- drivers/net/wan/x25_asy.c | 19 ------------------- drivers/tty/n_gsm.c | 11 ----------- drivers/tty/n_r3964.c | 22 ++++++++++++++++++++++ drivers/tty/tty_io.c | 3 +++ include/linux/tty_ldisc.h | 10 ++++++++-- net/nfc/nci/uart.c | 1 + 11 files changed, 36 insertions(+), 100 deletions(-) diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 963bb0309e25d..ae0dd57a8e996 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -821,6 +821,7 @@ static int __init hci_uart_init(void) hci_uart_ldisc.read = hci_uart_tty_read; hci_uart_ldisc.write = hci_uart_tty_write; hci_uart_ldisc.ioctl = hci_uart_tty_ioctl; + hci_uart_ldisc.compat_ioctl = hci_uart_tty_ioctl; hci_uart_ldisc.poll = hci_uart_tty_poll; hci_uart_ldisc.receive_buf = hci_uart_tty_receive; hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup; diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index f8ead9f9c77ea..5977b8a34ebe6 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -226,7 +226,7 @@ static int serport_ldisc_ioctl(struct tty_struct *tty, struct file *file, #ifdef CONFIG_COMPAT #define COMPAT_SPIOCSTYPE _IOW('q', 0x01, compat_ulong_t) -static long serport_ldisc_compat_ioctl(struct tty_struct *tty, +static int serport_ldisc_compat_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index d79a69dd2146d..17e6dcd2eb424 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #define SIXPACK_VERSION "Revision: 0.3.0" @@ -752,23 +751,6 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file, return err; } -#ifdef CONFIG_COMPAT -static long sixpack_compat_ioctl(struct tty_struct * tty, struct file * file, - unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - case SIOCGIFNAME: - case SIOCGIFENCAP: - case SIOCSIFENCAP: - case SIOCSIFHWADDR: - return sixpack_ioctl(tty, file, cmd, - (unsigned long)compat_ptr(arg)); - } - - return -ENOIOCTLCMD; -} -#endif - static struct tty_ldisc_ops sp_ldisc = { .owner = THIS_MODULE, .magic = TTY_LDISC_MAGIC, @@ -776,9 +758,6 @@ static struct tty_ldisc_ops sp_ldisc = { .open = sixpack_open, .close = sixpack_close, .ioctl = sixpack_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = sixpack_compat_ioctl, -#endif .receive_buf = sixpack_receive_buf, .write_wakeup = sixpack_write_wakeup, }; diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 13e4c1eff3536..802233d41b25e 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -35,7 +35,6 @@ #include #include #include -#include #include @@ -875,23 +874,6 @@ static int mkiss_ioctl(struct tty_struct *tty, struct file *file, return err; } -#ifdef CONFIG_COMPAT -static long mkiss_compat_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - case SIOCGIFNAME: - case SIOCGIFENCAP: - case SIOCSIFENCAP: - case SIOCSIFHWADDR: - return mkiss_ioctl(tty, file, cmd, - (unsigned long)compat_ptr(arg)); - } - - return -ENOIOCTLCMD; -} -#endif - /* * Handle the 'receiver data ready' interrupt. * This function is called by the 'tty_io' module in the kernel when @@ -966,9 +948,6 @@ static struct tty_ldisc_ops ax_ldisc = { .open = mkiss_open, .close = mkiss_close, .ioctl = mkiss_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = mkiss_compat_ioctl, -#endif .receive_buf = mkiss_receive_buf, .write_wakeup = mkiss_write_wakeup }; diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index b008266e91eab..9757f1fc104f0 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -79,7 +79,6 @@ #include #include #include -#include #include #include #include @@ -1167,27 +1166,6 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, } } -#ifdef CONFIG_COMPAT -static long slip_compat_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - case SIOCGIFNAME: - case SIOCGIFENCAP: - case SIOCSIFENCAP: - case SIOCSIFHWADDR: - case SIOCSKEEPALIVE: - case SIOCGKEEPALIVE: - case SIOCSOUTFILL: - case SIOCGOUTFILL: - return slip_ioctl(tty, file, cmd, - (unsigned long)compat_ptr(arg)); - } - - return -ENOIOCTLCMD; -} -#endif - /* VSV changes start here */ #ifdef CONFIG_SLIP_SMART /* function do_ioctl called from net/core/dev.c @@ -1280,9 +1258,6 @@ static struct tty_ldisc_ops sl_ldisc = { .close = slip_close, .hangup = slip_hangup, .ioctl = slip_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = slip_compat_ioctl, -#endif .receive_buf = slip_receive_buf, .write_wakeup = slip_write_wakeup, }; diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 74c06a5f586f7..1098263ab862e 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include "x25_asy.h" @@ -703,21 +702,6 @@ static int x25_asy_ioctl(struct tty_struct *tty, struct file *file, } } -#ifdef CONFIG_COMPAT -static long x25_asy_compat_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - case SIOCGIFNAME: - case SIOCSIFHWADDR: - return x25_asy_ioctl(tty, file, cmd, - (unsigned long)compat_ptr(arg)); - } - - return -ENOIOCTLCMD; -} -#endif - static int x25_asy_open_dev(struct net_device *dev) { struct x25_asy *sl = netdev_priv(dev); @@ -769,9 +753,6 @@ static struct tty_ldisc_ops x25_ldisc = { .open = x25_asy_open_tty, .close = x25_asy_close_tty, .ioctl = x25_asy_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = x25_asy_compat_ioctl, -#endif .receive_buf = x25_asy_receive_buf, .write_wakeup = x25_asy_write_wakeup, }; diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 86b7e20ffd7f1..6f7da9a9d76f0 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2614,14 +2614,6 @@ static int gsmld_ioctl(struct tty_struct *tty, struct file *file, } } -#ifdef CONFIG_COMPAT -static long gsmld_compat_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - return gsmld_ioctl(tty, file, cmd, arg); -} -#endif - /* * Network interface * @@ -2833,9 +2825,6 @@ static struct tty_ldisc_ops tty_ldisc_packet = { .flush_buffer = gsmld_flush_buffer, .read = gsmld_read, .write = gsmld_write, -#ifdef CONFIG_COMPAT - .compat_ioctl = gsmld_compat_ioctl, -#endif .ioctl = gsmld_ioctl, .poll = gsmld_poll, .receive_buf = gsmld_receive_buf, diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c index dbf1ab36758eb..749a608c40b02 100644 --- a/drivers/tty/n_r3964.c +++ b/drivers/tty/n_r3964.c @@ -134,6 +134,10 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, const unsigned char *buf, size_t nr); static int r3964_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); +#ifdef CONFIG_COMPAT +static int r3964_compat_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg); +#endif static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old); static __poll_t r3964_poll(struct tty_struct *tty, struct file *file, struct poll_table_struct *wait); @@ -149,6 +153,9 @@ static struct tty_ldisc_ops tty_ldisc_N_R3964 = { .read = r3964_read, .write = r3964_write, .ioctl = r3964_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = r3964_compat_ioctl, +#endif .set_termios = r3964_set_termios, .poll = r3964_poll, .receive_buf = r3964_receive_buf, @@ -1210,6 +1217,21 @@ static int r3964_ioctl(struct tty_struct *tty, struct file *file, } } +#ifdef CONFIG_COMPAT +static int r3964_compat_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + case R3964_ENABLE_SIGNALS: + case R3964_SETPRIORITY: + case R3964_USE_BCC: + return r3964_ioctl(tty, file, cmd, arg); + default: + return -ENOIOCTLCMD; + } +} +#endif + static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old) { TRACE_L("set_termios"); diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 1a55c3e202992..cd8df45f09d90 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2824,6 +2824,9 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, return hung_up_tty_compat_ioctl(file, cmd, arg); if (ld->ops->compat_ioctl) retval = ld->ops->compat_ioctl(tty, file, cmd, arg); + if (retval == -ENOIOCTLCMD && ld->ops->ioctl) + retval = ld->ops->ioctl(tty, file, + (unsigned long)compat_ptr(cmd), arg); tty_ldisc_deref(ld); return retval; diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index 840894ca3fc02..b1e6043e99175 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -54,11 +54,17 @@ * low-level driver can "grab" an ioctl request before the line * discpline has a chance to see it. * - * long (*compat_ioctl)(struct tty_struct * tty, struct file * file, + * int (*compat_ioctl)(struct tty_struct * tty, struct file * file, * unsigned int cmd, unsigned long arg); * * Process ioctl calls from 32-bit process on 64-bit system * + * NOTE: only ioctls that are neither "pointer to compatible + * structure" nor tty-generic. Something private that takes + * an integer or a pointer to wordsize-sensitive structure + * belongs here, but most of ldiscs will happily leave + * it NULL. + * * void (*set_termios)(struct tty_struct *tty, struct ktermios * old); * * This function notifies the line discpline that a change has @@ -184,7 +190,7 @@ struct tty_ldisc_ops { const unsigned char *buf, size_t nr); int (*ioctl)(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); - long (*compat_ioctl)(struct tty_struct *tty, struct file *file, + int (*compat_ioctl)(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); void (*set_termios)(struct tty_struct *tty, struct ktermios *old); __poll_t (*poll)(struct tty_struct *, struct file *, diff --git a/net/nfc/nci/uart.c b/net/nfc/nci/uart.c index a66f102c6c013..d1fa0f22c10c0 100644 --- a/net/nfc/nci/uart.c +++ b/net/nfc/nci/uart.c @@ -465,6 +465,7 @@ static struct tty_ldisc_ops nci_uart_ldisc = { .receive_buf = nci_uart_tty_receive, .write_wakeup = nci_uart_tty_wakeup, .ioctl = nci_uart_tty_ioctl, + .compat_ioctl = nci_uart_tty_ioctl, }; static int __init nci_uart_init(void) From ce5a983191ce466cbe35e240ac09e28cca3e50c9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 14 Sep 2018 14:46:18 -0400 Subject: [PATCH 53/53] kill TIOCSERGSTRUCT Once upon a time a bunch of serial drivers used to provide that; today it's only amiserial and it's FUBAR - the structure being copied to userland includes kernel pointers, fields with config-dependent size, etc. No userland code using it could possibly survive - e.g. enabling lockdep definitely changes the layout. Besides, it's a massive infoleak. Kill it. If somebody needs that data for debugging purposes, they can bloody well expose it saner ways. Assuming anyone does debugging of amiserial in the first place, that is. Signed-off-by: Al Viro --- arch/ia64/hp/sim/simserial.c | 4 +--- drivers/tty/amiserial.c | 8 +------- net/bluetooth/rfcomm/tty.c | 4 ---- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index 759a3bbec1838..7aeb48a185763 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -309,14 +309,12 @@ static int rs_getserial(struct tty_struct *tty, struct serial_struct *ss) static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { - if ((cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && - (cmd != TIOCMIWAIT)) { + if ((cmd != TIOCSERCONFIG) && (cmd != TIOCMIWAIT)) { if (tty_io_error(tty)) return -EIO; } switch (cmd) { - case TIOCSERGSTRUCT: case TIOCMIWAIT: return 0; case TIOCSERCONFIG: diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 6992adf826f4a..8330fd809a05f 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1215,7 +1215,7 @@ static int rs_ioctl(struct tty_struct *tty, if (serial_paranoia_check(info, tty->name, "rs_ioctl")) return -ENODEV; - if ((cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && + if ((cmd != TIOCSERCONFIG) && (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { if (tty_io_error(tty)) return -EIO; @@ -1228,12 +1228,6 @@ static int rs_ioctl(struct tty_struct *tty, case TIOCSERGETLSR: /* Get line status register */ return get_lsr_info(info, argp); - case TIOCSERGSTRUCT: - if (copy_to_user(argp, - info, sizeof(struct serial_state))) - return -EFAULT; - return 0; - /* * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change * - mask passed in arg for lines of interest diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index ba4f59389405d..0c7d31c6c18cc 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -839,10 +839,6 @@ static int rfcomm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned l BT_DBG("TIOCMIWAIT"); break; - case TIOCSERGSTRUCT: - BT_ERR("TIOCSERGSTRUCT is not supported"); - return -ENOIOCTLCMD; - case TIOCSERGETLSR: BT_ERR("TIOCSERGETLSR is not supported"); return -ENOIOCTLCMD;