diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-24 14:43:41 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-24 14:43:41 +0100 |
commit | 44adbac8f7217040be97928cd19998259d9d4418 (patch) | |
tree | c1c6ac9aa4d47801dc9133d6d641286631a8f4b4 /drivers/staging | |
parent | 08ffb584d9eb17940321317ef6c9c7383ad4f149 (diff) | |
parent | ce5a983191ce466cbe35e240ac09e28cca3e50c9 (diff) |
Merge branch 'work.tty-ioctl' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull tty ioctl updates from Al Viro:
"This is the compat_ioctl work related to tty ioctls.
Quite a bit of dead code taken out, all tty-related stuff gone from
fs/compat_ioctl.c. A bunch of compat bugs fixed - some still remain,
but all more or less generic tty-related ioctls should be covered
(remaining issues are in things like driver-private ioctls in a pcmcia
serial card driver not getting properly handled in 32bit processes on
64bit host, etc)"
* 'work.tty-ioctl' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (53 commits)
kill TIOCSERGSTRUCT
change semantics of ldisc ->compat_ioctl()
kill TIOCSER[SG]WILD
synclink_gt(): fix compat_ioctl()
pty: fix compat ioctls
compat_ioctl - kill keyboard ioctl handling
gigaset: add ->compat_ioctl()
vt_compat_ioctl(): clean up, use compat_ptr() properly
gigaset: don't try to printk userland buffer contents
dgnc: don't bother with (empty) stub for TCXONC
dgnc: leave TIOC[GS]SOFTCAR to ldisc
remove fallback to drivers for TIOCGICOUNT
dgnc: break-related ioctls won't reach ->ioctl()
kill the rest of tty COMPAT_IOCTL() entries
dgnc: TIOCM... won't reach ->ioctl()
isdn_tty: TCSBRK{,P} won't reach ->ioctl()
kill capinc_tty_ioctl()
take compat TIOC[SG]SERIAL treatment into tty_compat_ioctl()
synclink: reduce pointless checks in ->ioctl()
complete ->[sg]et_serial() switchover
...
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/dgnc/dgnc_tty.c | 218 | ||||
-rw-r--r-- | drivers/staging/fwserial/fwserial.c | 66 | ||||
-rw-r--r-- | drivers/staging/greybus/uart.c | 47 |
3 files changed, 46 insertions, 285 deletions
diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index f91eaa1c3b67..b8f865018950 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) @@ -2184,116 +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 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); - - 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; - - 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: /* * The linux tty driver doesn't have a flush @@ -2370,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); diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index fa0dd425b454..173f451b86b7 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) diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index 8a006323c3c1..3313cb0b60af 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 = { |