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
  ...
This commit is contained in:
Linus Torvalds 2018-10-24 14:43:41 +01:00
commit 44adbac8f7
56 changed files with 778 additions and 1521 deletions

View File

@ -297,29 +297,29 @@ 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) &&
(cmd != TIOCMIWAIT)) {
if ((cmd != TIOCSERCONFIG) && (cmd != TIOCMIWAIT)) {
if (tty_io_error(tty))
return -EIO;
}
switch (cmd) {
case TIOCGSERIAL:
case TIOCSSERIAL:
case TIOCSERGSTRUCT:
case TIOCMIWAIT:
return 0;
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;
}
@ -448,6 +448,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,
};

View File

@ -823,6 +823,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;

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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,

View File

@ -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;
@ -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,

View File

@ -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);

View File

@ -34,7 +34,6 @@
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/semaphore.h>
#include <linux/compat.h>
#include <linux/refcount.h>
#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,
};

View File

@ -35,7 +35,6 @@
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/jiffies.h>
#include <linux/compat.h>
#include <net/ax25.h>
@ -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
};

View File

@ -79,7 +79,6 @@
#include <linux/rtnetlink.h>
#include <linux/if_arp.h>
#include <linux/if_slip.h>
#include <linux/compat.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/slab.h>
@ -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,
};

View File

@ -33,7 +33,6 @@
#include <linux/lapb.h>
#include <linux/init.h>
#include <linux/rtnetlink.h>
#include <linux/compat.h>
#include <linux/slab.h>
#include <net/x25device.h>
#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,
};

View File

@ -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);

View File

@ -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;
struct fwtty_port *port = tty->driver_data;
if (copy_from_user(&tmp, info, sizeof(tmp)))
return -EFAULT;
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)

View File

@ -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;
struct gb_tty *gb_tty = tty->driver_data;
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 =
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 = {

View File

@ -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 @@ check_and_exit:
return retval;
}
/*
* get_lsr_info - get line status register info
*
@ -1224,30 +1215,19 @@ 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 != 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;
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
@ -1288,12 +1268,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;
}
@ -1607,6 +1581,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,
};

View File

@ -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,
};

View File

@ -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)

View File

@ -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 = {

View File

@ -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 @@ copy:
}
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;
}
}
info->port.close_delay = ss->close_delay * HZ / 100;
new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS);
new_serial.flags |= (info->port.flags & ASYNC_FLAGS);
MoxaSetFifo(info, ss->type == PORT_16550A);
MoxaSetFifo(info, new_serial.type == PORT_16550A);
info->type = new_serial.type;
info->type = ss->type;
mutex_unlock(&info->port.mutex);
return 0;
}

View File

@ -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)
return -ENODEV;
if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
return -EFAULT;
if (tty->index == MXSER_PORTS)
return -ENOTTY;
if (tty_io_error(tty))
return -EIO;
if (new_serial.irq != info->board->irq ||
new_serial.port != info->ioaddr)
mutex_lock(&port->mutex);
if (!info->ioaddr) {
mutex_unlock(&port->mutex);
return -ENODEV;
}
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,
};

View File

@ -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,

View File

@ -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");

View File

@ -28,6 +28,7 @@
#include <linux/mount.h>
#include <linux/file.h>
#include <linux/ioctl.h>
#include <linux/compat.h>
#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

View File

@ -778,17 +778,13 @@ out:
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;
struct uart_state *state = tty->driver_data;
struct tty_port *port = &state->port;
if (uart_get_info(port, &tmp) < 0)
return -EIO;
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,26 +1319,11 @@ 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);
up_write(&tty->termios_rwsem);
break;
case TIOCSERGWILD: /* obsolete */
case TIOCSERSWILD: /* obsolete */
ret = 0;
break;
}
if (ret != -ENOIOCTLCMD)
@ -2413,6 +2392,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,

View File

@ -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;
}

View File

@ -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;
}
@ -1186,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;
@ -1213,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;
}

View File

@ -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;
}

View File

@ -97,6 +97,7 @@
#include <linux/seq_file.h>
#include <linux/serial.h>
#include <linux/ratelimit.h>
#include <linux/compat.h>
#include <linux/uaccess.h>
@ -2292,34 +2293,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
@ -2488,22 +2461,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 -ENOTTY;
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 -ENOTTY;
err = tty->ops->get_serial(tty, &v);
if (!err && copy_to_user(ss, &v, sizeof(struct serial_struct)))
err = -EFAULT;
return err;
}
/*
@ -2566,8 +2557,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;
@ -2622,11 +2611,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:
@ -2637,8 +2622,9 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
break;
case TIOCSSERIAL:
tty_warn_deprecated_flags(p);
break;
return tty_tiocsserial(tty, p);
case TIOCGSERIAL:
return tty_tiocgserial(tty, p);
case TIOCGPTPEER:
/* Special because the struct file is needed */
return ptm_open_peer(file, tty, (int)arg);
@ -2666,6 +2652,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)
{
@ -2673,9 +2734,90 @@ 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;
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)
@ -2687,8 +2829,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);
else
retval = n_tty_compat_ioctl_helper(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;

View File

@ -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

View File

@ -1175,17 +1175,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
@ -1201,17 +1197,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
@ -1236,21 +1229,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);
}

View File

@ -884,37 +884,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);
@ -999,12 +990,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) {
@ -1931,6 +1916,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,
};

View File

@ -397,38 +397,16 @@ err_free:
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,

View File

@ -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,

View File

@ -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,

View File

@ -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 @@ check_and_exit:
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:

View File

@ -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;
struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
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;
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,

View File

@ -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,

View File

@ -1786,69 +1786,20 @@ 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)
static int get_serial_info(struct tty_struct *tty,
struct serial_struct *ss)
{
unsigned int mcr;
unsigned int arg;
struct usb_serial_port *port = tty->driver_data;
struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
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)
{
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;
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;
}
@ -1867,18 +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);
/* 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,
(struct serial_struct __user *)arg);
}
return -ENOIOCTLCMD;
@ -2015,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,

View File

@ -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;
struct usb_serial_port *port = tty->driver_data;
struct moschip_port *mos7840_port = mos7840_get_port_private(port);
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;
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,

View File

@ -328,40 +328,21 @@ 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)
{
struct serial_struct tmp;
memset(&tmp, 0x00, sizeof(tmp));
/* 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;
return 0;
}
static int opticon_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);
}
return -ENOIOCTLCMD;
/* fake emulate a 16550 uart to make userspace code happy */
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_port_probe(struct usb_serial_port *port)
@ -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,

View File

@ -1966,7 +1966,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,

View File

@ -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,

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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 @@ free_data:
}
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;

View File

@ -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 -ENOTTY;
}
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 -ENOTTY;
}
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,

View File

@ -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);

View File

@ -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;
struct usb_serial_port *port = tty->driver_data;
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 ?
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)

View File

@ -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;
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;
if (copy_to_user(user_arg, &serstruct, sizeof(serstruct)))
return -EFAULT;
break;
default:
break;
}
return -ENOIOCTLCMD;
return 0;
}

View File

@ -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)
@ -707,60 +644,8 @@ 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 */
/* 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)
#ifdef TIOCSRS485
COMPATIBLE_IOCTL(TIOCSRS485)
#endif
#ifdef TIOCGRS485
COMPATIBLE_IOCTL(TIOCGRS485)
#endif
#ifdef TCGETS2
COMPATIBLE_IOCTL(TCGETS2)
COMPATIBLE_IOCTL(TCSETS2)
COMPATIBLE_IOCTL(TCSETSW2)
COMPATIBLE_IOCTL(TCSETSF2)
#endif
/* Little f */
COMPATIBLE_IOCTL(FIOCLEX)
COMPATIBLE_IOCTL(FIONCLEX)
@ -775,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)
@ -1133,11 +1001,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 */
@ -1223,21 +1086,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
* 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. */
@ -1293,10 +1141,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:
@ -1316,24 +1160,11 @@ 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:
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);
}

View File

@ -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 */

View File

@ -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);

View File

@ -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 *,

View File

@ -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);

View File

@ -839,18 +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;
case TIOCSERGETLSR:
BT_ERR("TIOCSERGETLSR is not supported");
return -ENOIOCTLCMD;

View File

@ -463,6 +463,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)