]> git.hungrycats.org Git - linux/commitdiff
[PATCH] more serial driver fixups
authorAndrew Morton <akpm@osdl.org>
Sun, 22 Feb 2004 15:00:39 +0000 (07:00 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Sun, 22 Feb 2004 15:00:39 +0000 (07:00 -0800)
From: Russell King <rmk@arm.linux.org.uk>

Here is a patch which updates various serial drivers in the kernel to make
them less broken than they were before.  Nevertheless, they are still
broken.

The improvement is to make these drivers use the tiocmget/tiocmset methods,
which are present in the 2.6 kernel.

Many of these have been incorrectly converted from the old global IRQ
locking without regard for SMP issues, or still use the old global IRQ
locking methods which are no longer present in 2.6 kernels.

The full message thread can be found at:

http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=1dvnl-5Pr-1%40gated-at.bofh.it&rnum=1&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DISO-8859-1%26q%3DOutstanding%2Bfixups%26btnG%3DGoogle%2BSearch%26meta%3Dgroup%253Dlinux.kernel

13 files changed:
drivers/char/amiserial.c
drivers/char/epca.c
drivers/char/esp.c
drivers/char/isicom.c
drivers/char/moxa.c
drivers/char/mxser.c
drivers/char/pcxx.c
drivers/char/riscom8.c
drivers/char/serial167.c
drivers/char/specialix.c
drivers/sbus/char/aurora.c
drivers/serial/68360serial.c
drivers/tc/zs.c

index bc506dbff14223af6ceba6c4ce58418fbc165f4a..3dc61d41b33d36fabee9255dbbbf56e844773c25 100644 (file)
@@ -1248,57 +1248,48 @@ static int get_lsr_info(struct async_struct * info, unsigned int *value)
 }
 
 
-static int get_modem_info(struct async_struct * info, unsigned int *value)
+static int rs_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct async_struct * info = (struct async_struct *)tty->driver_data;
        unsigned char control, status;
-       unsigned int result;
        unsigned long flags;
 
+       if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
+               return -ENODEV;
+       if (tty->flags & (1 << TTY_IO_ERROR))
+               return -EIO;
+
        control = info->MCR;
        local_irq_save(flags);
        status = ciab.pra;
        local_irq_restore(flags);
-       result =  ((control & SER_RTS) ? TIOCM_RTS : 0)
+       return    ((control & SER_RTS) ? TIOCM_RTS : 0)
                | ((control & SER_DTR) ? TIOCM_DTR : 0)
                | (!(status  & SER_DCD) ? TIOCM_CAR : 0)
                | (!(status  & SER_DSR) ? TIOCM_DSR : 0)
                | (!(status  & SER_CTS) ? TIOCM_CTS : 0);
-       if (copy_to_user(value, &result, sizeof(int)))
-               return -EFAULT;
-       return 0;
 }
 
-static int set_modem_info(struct async_struct * info, unsigned int cmd,
-                         unsigned int *value)
+static int rs_tiocmset(struct tty_struct *tty, struct file *file,
+                      unsigned int set, unsigned int clear)
 {
-       unsigned int arg;
+       struct async_struct * info = (struct async_struct *)tty->driver_data;
        unsigned long flags;
 
-       if (copy_from_user(&arg, value, sizeof(int)))
-               return -EFAULT;
+       if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
+               return -ENODEV;
+       if (tty->flags & (1 << TTY_IO_ERROR))
+               return -EIO;
 
-       switch (cmd) {
-       case TIOCMBIS: 
-               if (arg & TIOCM_RTS)
-                       info->MCR |= SER_RTS;
-               if (arg & TIOCM_DTR)
-                       info->MCR |= SER_DTR;
-               break;
-       case TIOCMBIC:
-               if (arg & TIOCM_RTS)
-                       info->MCR &= ~SER_RTS;
-               if (arg & TIOCM_DTR)
-                       info->MCR &= ~SER_DTR;
-               break;
-       case TIOCMSET:
-               info->MCR = ((info->MCR & ~(SER_RTS | SER_DTR))
-                            | ((arg & TIOCM_RTS) ? SER_RTS : 0)
-                            | ((arg & TIOCM_DTR) ? SER_DTR : 0));
-               break;
-       default:
-               return -EINVAL;
-       }
        local_irq_save(flags);
+       if (set & TIOCM_RTS)
+               info->MCR |= SER_RTS;
+       if (set & TIOCM_DTR)
+               info->MCR |= SER_DTR;
+       if (clear & TIOCM_RTS)
+               info->MCR &= ~SER_RTS;
+       if (clear & TIOCM_DTR)
+               info->MCR &= ~SER_DTR;
        rtsdtr_ctrl(info->MCR);
        local_irq_restore(flags);
        return 0;
@@ -1344,12 +1335,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
        }
 
        switch (cmd) {
-               case TIOCMGET:
-                       return get_modem_info(info, (unsigned int *) arg);
-               case TIOCMBIS:
-               case TIOCMBIC:
-               case TIOCMSET:
-                       return set_modem_info(info, cmd, (unsigned int *) arg);
                case TIOCGSERIAL:
                        return get_serial_info(info,
                                               (struct serial_struct *) arg);
@@ -2045,6 +2030,8 @@ static struct tty_operations serial_ops = {
        .send_xchar = rs_send_xchar,
        .wait_until_sent = rs_wait_until_sent,
        .read_proc = rs_read_proc,
+       .tiocmget = rs_tiocmget,
+       .tiocmset = rs_tiocmset,
 };
 
 /*
index 146a7516cd4cf9b2a270663ee258a787be8d663f..1c70202168cd32bd87eaadb96bb5a20a4029e409 100644 (file)
@@ -2931,6 +2931,96 @@ static int info_ioctl(struct tty_struct *tty, struct file * file,
 }
 /* --------------------- Begin pc_ioctl  ----------------------- */
 
+static int pc_tiocmget(struct tty_struct *tty, struct file *file)
+{
+       struct channel *ch = (struct channel *) tty->driver_data;
+       volatile struct board_chan *bc;
+       unsigned int mstat, mflag = 0;
+       unsigned long flags;
+
+       if (ch)
+               bc = ch->brdchan;
+       else
+       {
+               printk(KERN_ERR "<Error> - ch is NULL in pc_tiocmget!\n");
+               return(-EINVAL);
+       }
+
+       save_flags(flags);
+       cli();
+       globalwinon(ch);
+       mstat = bc->mstat;
+       memoff(ch);
+       restore_flags(flags);
+
+       if (mstat & ch->m_dtr)
+               mflag |= TIOCM_DTR;
+
+       if (mstat & ch->m_rts)
+               mflag |= TIOCM_RTS;
+
+       if (mstat & ch->m_cts)
+               mflag |= TIOCM_CTS;
+
+       if (mstat & ch->dsr)
+               mflag |= TIOCM_DSR;
+
+       if (mstat & ch->m_ri)
+               mflag |= TIOCM_RI;
+
+       if (mstat & ch->dcd)
+               mflag |= TIOCM_CD;
+
+       return mflag;
+}
+
+static int pc_tiocmset(struct tty_struct *tty, struct file *file,
+                      unsigned int set, unsigned int clear)
+{
+       struct channel *ch = (struct channel *) tty->driver_data;
+       unsigned long flags;
+
+       if (!ch) {
+               printk(KERN_ERR "<Error> - ch is NULL in pc_tiocmset!\n");
+               return(-EINVAL);
+       }
+
+       save_flags(flags);
+       cli();
+       /*
+        * I think this modemfake stuff is broken.  It doesn't
+        * correctly reflect the behaviour desired by the TIOCM*
+        * ioctls.  Therefore this is probably broken.
+        */
+       if (set & TIOCM_RTS) {
+               ch->modemfake |= ch->m_rts;
+               ch->modem |= ch->m_rts;
+       }
+       if (set & TIOCM_DTR) {
+               ch->modemfake |= ch->m_dtr;
+               ch->modem |= ch->m_dtr;
+       }
+       if (clear & TIOCM_RTS) {
+               ch->modemfake |= ch->m_rts;
+               ch->modem &= ~ch->m_rts;
+       }
+       if (clear & TIOCM_DTR) {
+               ch->modemfake |= ch->m_dtr;
+               ch->modem &= ~ch->m_dtr;
+       }
+
+       globalwinon(ch);
+
+       /*  --------------------------------------------------------------
+               The below routine generally sets up parity, baud, flow control
+               issues, etc.... It effect both control flags and input flags.
+       ------------------------------------------------------------------ */
+
+       epcaparam(tty,ch);
+       memoff(ch);
+       restore_flags(flags);
+}
+
 static int pc_ioctl(struct tty_struct *tty, struct file * file,
                    unsigned int cmd, unsigned long arg)
 { /* Begin pc_ioctl */
@@ -3021,90 +3111,15 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
                }
 
                case TIOCMODG:
-               case TIOCMGET:
-
-                       mflag = 0;
-
-                       cli();
-                       globalwinon(ch);
-                       mstat = bc->mstat;
-                       memoff(ch);
-                       restore_flags(flags);
-
-                       if (mstat & ch->m_dtr)
-                               mflag |= TIOCM_DTR;
-
-                       if (mstat & ch->m_rts)
-                               mflag |= TIOCM_RTS;
-
-                       if (mstat & ch->m_cts)
-                               mflag |= TIOCM_CTS;
-
-                       if (mstat & ch->dsr)
-                               mflag |= TIOCM_DSR;
-
-                       if (mstat & ch->m_ri)
-                               mflag |= TIOCM_RI;
-
-                       if (mstat & ch->dcd)
-                               mflag |= TIOCM_CD;
-
-                       error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long));
-
-                       if (error)
-                               return error;
-
-                       putUser(mflag, (unsigned int *) arg);
-
+                       mflag = pc_tiocmget(tty, file);
+                       if (putUser(mflag, (unsigned int *) arg))
+                               return -EFAULT;
                        break;
 
-               case TIOCMBIS:
-               case TIOCMBIC:
                case TIOCMODS:
-               case TIOCMSET:
-
-                       getUser(mstat, (unsigned int *)arg);
-
-                       mflag = 0;
-                       if (mstat & TIOCM_DTR)
-                               mflag |= ch->m_dtr;
-
-                       if (mstat & TIOCM_RTS)
-                               mflag |= ch->m_rts;
-
-                       switch (cmd) 
-                       { /* Begin switch cmd */
-
-                               case TIOCMODS:
-                               case TIOCMSET:
-                                       ch->modemfake = ch->m_dtr|ch->m_rts;
-                                       ch->modem = mflag;
-                                       break;
-
-                               case TIOCMBIS:
-                                       ch->modemfake |= mflag;
-                                       ch->modem |= mflag;
-                                       break;
-
-                               case TIOCMBIC:
-                                       ch->modemfake |= mflag;
-                                       ch->modem &= ~mflag;
-                                       break;
-
-                       } /* End switch cmd */
-
-                       cli();
-                       globalwinon(ch);
-
-                       /*  --------------------------------------------------------------
-                               The below routine generally sets up parity, baud, flow control 
-                               issues, etc.... It effect both control flags and input flags.
-                       ------------------------------------------------------------------ */
-
-                       epcaparam(tty,ch);
-                       memoff(ch);
-                       restore_flags(flags);
-                       break;
+                       if (getUser(mstat, (unsigned int *)arg))
+                               return -EFAULT;
+                       return pc_tiocmset(tty, file, mstat, ~mstat);
 
                case TIOCSDTR:
                        ch->omodem |= ch->m_dtr;
index ad37fa1d09f97991d696f46022fa2b043f4ac23f..1d0ee261c6b1b5a1eaf99da3eac13abfe5b56e07 100644 (file)
@@ -1753,55 +1753,52 @@ static int get_lsr_info(struct esp_struct * info, unsigned int *value)
 }
 
 
-static int get_modem_info(struct esp_struct * info, unsigned int *value)
+static int esp_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct esp_struct * info = (struct esp_struct *)tty->driver_data;
        unsigned char control, status;
-       unsigned int result;
+
+       if (serial_paranoia_check(info, tty->name, __FUNCTION__))
+               return -ENODEV;
+       if (tty->flags & (1 << TTY_IO_ERROR))
+               return -EIO;
 
        control = info->MCR;
        cli();
        serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT);
        status = serial_in(info, UART_ESI_STAT2);
        sti();
-       result =  ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
+       return    ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
                | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
                | ((status  & UART_MSR_DCD) ? TIOCM_CAR : 0)
                | ((status  & UART_MSR_RI) ? TIOCM_RNG : 0)
                | ((status  & UART_MSR_DSR) ? TIOCM_DSR : 0)
                | ((status  & UART_MSR_CTS) ? TIOCM_CTS : 0);
-       return put_user(result,value);
 }
 
-static int set_modem_info(struct esp_struct * info, unsigned int cmd,
-                         unsigned int *value)
+static int esp_tiocmset(struct tty_struct *tty, struct file *file,
+                       unsigned int set, unsigned int clear)
 {
+       struct esp_struct * info = (struct esp_struct *)tty->driver_data;
        unsigned int arg;
 
-       if (get_user(arg, value))
-               return -EFAULT;
+       if (serial_paranoia_check(info, tty->name, __FUNCTION__))
+               return -ENODEV;
+       if (tty->flags & (1 << TTY_IO_ERROR))
+               return -EIO;
 
-       switch (cmd) {
-       case TIOCMBIS: 
-               if (arg & TIOCM_RTS)
-                       info->MCR |= UART_MCR_RTS;
-               if (arg & TIOCM_DTR)
-                       info->MCR |= UART_MCR_DTR;
-               break;
-       case TIOCMBIC:
-               if (arg & TIOCM_RTS)
-                       info->MCR &= ~UART_MCR_RTS;
-               if (arg & TIOCM_DTR)
-                       info->MCR &= ~UART_MCR_DTR;
-               break;
-       case TIOCMSET:
-               info->MCR = ((info->MCR & ~(UART_MCR_RTS | UART_MCR_DTR))
-                            | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
-                            | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0));
-               break;
-       default:
-               return -EINVAL;
-       }
        cli();
+
+       if (set & TIOCM_RTS)
+               info->MCR |= UART_MCR_RTS;
+       if (set & TIOCM_DTR)
+               info->MCR |= UART_MCR_DTR;
+
+       if (clear & TIOCM_RTS)
+               info->MCR &= ~UART_MCR_RTS;
+       if (clear & TIOCM_DTR)
+               info->MCR &= ~UART_MCR_DTR;
+
        serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
        serial_out(info, UART_ESI_CMD2, UART_MCR);
        serial_out(info, UART_ESI_CMD2, info->MCR);
@@ -1853,12 +1850,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
        }
        
        switch (cmd) {
-               case TIOCMGET:
-                       return get_modem_info(info, (unsigned int *) arg);
-               case TIOCMBIS:
-               case TIOCMBIC:
-               case TIOCMSET:
-                       return set_modem_info(info, cmd, (unsigned int *) arg);
                case TIOCGSERIAL:
                        return get_serial_info(info,
                                               (struct serial_struct *) arg);
@@ -2444,6 +2435,8 @@ static struct tty_operations esp_ops = {
        .hangup = esp_hangup,
        .break_ctl = esp_break,
        .wait_until_sent = rs_wait_until_sent,
+       .tiocmget = esp_tiocmget,
+       .tiocmset = esp_tiocmset,
 };
 
 /*
index 82f76f1e6a9d9e47d8c2a492c7bc1da0231e34e7..ca84ac9fd8ff03f8121b9f78f1918931587c89a6 100644 (file)
@@ -1291,63 +1291,44 @@ static inline void isicom_send_break(struct isi_port * port, unsigned long lengt
 out:   restore_flags(flags);
 }
 
-static int isicom_get_modem_info(struct isi_port * port, unsigned int * value)
+static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct isi_port * port = (struct isi_port *) tty->driver_data;
        /* just send the port status */
-       unsigned int info;
        unsigned short status = port->status;
+
+       if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
+               return -ENODEV;
        
-       info =  ((status & ISI_RTS) ? TIOCM_RTS : 0) |
+       return  ((status & ISI_RTS) ? TIOCM_RTS : 0) |
                ((status & ISI_DTR) ? TIOCM_DTR : 0) |
                ((status & ISI_DCD) ? TIOCM_CAR : 0) |
                ((status & ISI_DSR) ? TIOCM_DSR : 0) |
                ((status & ISI_CTS) ? TIOCM_CTS : 0) |
                ((status & ISI_RI ) ? TIOCM_RI  : 0);
-       return put_user(info, (unsigned int *) value);
 }
 
-static int isicom_set_modem_info(struct isi_port * port, unsigned int cmd,
-                                       unsigned int * value)
+static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
+                          unsigned int set, unsigned int clear)
 {
+       struct isi_port * port = (struct isi_port *) tty->driver_data;
        unsigned int arg;
        unsigned long flags;
        
-       if(get_user(arg, value))
-               return -EFAULT;
+       if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
+               return -ENODEV;
        
        save_flags(flags); cli();
-       
-       switch(cmd) {
-               case TIOCMBIS:
-                       if (arg & TIOCM_RTS) 
-                               raise_rts(port);
-                       if (arg & TIOCM_DTR) 
-                               raise_dtr(port);
-                       break;
-               
-               case TIOCMBIC:
-                       if (arg & TIOCM_RTS)
-                               drop_rts(port);
-                       if (arg & TIOCM_DTR)
-                               drop_dtr(port); 
-                       break;
-                       
-               case TIOCMSET:
-                       if (arg & TIOCM_RTS)
-                               raise_rts(port);
-                       else
-                               drop_rts(port);
-                       
-                       if (arg & TIOCM_DTR)
-                               raise_dtr(port);
-                       else
-                               drop_dtr(port);
-                       break;
-               
-               default:
-                       restore_flags(flags);
-                       return -EINVAL;                 
-       }
+       if (set & TIOCM_RTS)
+               raise_rts(port);
+       if (set & TIOCM_DTR)
+               raise_dtr(port);
+
+       if (clear & TIOCM_RTS)
+               drop_rts(port);
+       if (clear & TIOCM_DTR)
+               drop_dtr(port);
+
        restore_flags(flags);
        return 0;
 }                      
@@ -1445,15 +1426,6 @@ static int isicom_ioctl(struct tty_struct * tty, struct file * filp,
                                (arg ? CLOCAL : 0));
                        return 0;       
                        
-               case TIOCMGET:
-                       return isicom_get_modem_info(port, (unsigned int*) arg);
-                       
-               case TIOCMBIS:
-               case TIOCMBIC:
-               case TIOCMSET:  
-                       return isicom_set_modem_info(port, cmd, 
-                                       (unsigned int *) arg);
-               
                case TIOCGSERIAL:
                        return isicom_get_serial_info(port, 
                                        (struct serial_struct *) arg);
@@ -1640,6 +1612,8 @@ static struct tty_operations isicom_ops = {
        .start  = isicom_start,
        .hangup = isicom_hangup,
        .flush_buffer   = isicom_flush_buffer,
+       .tiocmget       = isicom_tiocmget,
+       .tiocmset       = isicom_tiocmset,
 };
 
 static int register_drivers(void)
index d3eaf6f3fc173ac8ab2c3050de8ba1d0aa57a2e3..55ac334ec46446bf395787ae4bf32f7bfe0c46f1 100644 (file)
@@ -232,6 +232,9 @@ static void moxa_set_termios(struct tty_struct *, struct termios *);
 static void moxa_stop(struct tty_struct *);
 static void moxa_start(struct tty_struct *);
 static void moxa_hangup(struct tty_struct *);
+static int moxa_tiocmget(struct tty_struct *tty, struct file *file);
+static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
+                        unsigned int set, unsigned int clear);
 static void moxa_poll(unsigned long);
 static void set_tty_param(struct tty_struct *);
 static int block_till_ready(struct tty_struct *, struct file *,
@@ -289,6 +292,8 @@ static struct tty_operations moxa_ops = {
        .stop = moxa_stop,
        .start = moxa_start,
        .hangup = moxa_hangup,
+       .tiocmget = moxa_tiocmget,
+       .tiocmset = moxa_tiocmset,
 };
 
 static int __init moxa_init(void)
@@ -742,6 +747,55 @@ static void moxa_put_char(struct tty_struct *tty, unsigned char c)
        ch->statusflags |= LOWWAIT;
 }
 
+static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
+{
+       struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
+       int port;
+       int flag = 0, dtr, rts;
+
+       port = PORTNO(tty);
+       if ((port != MAX_PORTS) && (!ch))
+               return (-EINVAL);
+
+       MoxaPortGetLineOut(ch->port, &dtr, &rts);
+       if (dtr)
+               flag |= TIOCM_DTR;
+       if (rts)
+               flag |= TIOCM_RTS;
+       dtr = MoxaPortLineStatus(ch->port);
+       if (dtr & 1)
+               flag |= TIOCM_CTS;
+       if (dtr & 2)
+               flag |= TIOCM_DSR;
+       if (dtr & 4)
+               flag |= TIOCM_CD;
+       return flag;
+}
+
+static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
+                        unsigned int set, unsigned int clear)
+{
+       struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
+       int port;
+       int flag = 0, dtr, rts;
+
+       port = PORTNO(tty);
+       if ((port != MAX_PORTS) && (!ch))
+               return (-EINVAL);
+
+       MoxaPortGetLineOut(ch->port, &dtr, &rts);
+       if (set & TIOCM_RTS)
+               rts = 1;
+       if (set & TIOCM_DTR)
+               dtr = 1;
+       if (clear & TIOCM_RTS)
+               rts = 0;
+       if (clear & TIOCM_DTR)
+               dtr = 0;
+       MoxaPortLineCtrl(ch->port, dtr, rts);
+       return 0;
+}
+
 static int moxa_ioctl(struct tty_struct *tty, struct file *file,
                      unsigned int cmd, unsigned long arg)
 {
@@ -785,51 +839,6 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
                else
                        ch->asyncflags |= ASYNC_CHECK_CD;
                return (0);
-       case TIOCMGET:
-               flag = 0;
-               MoxaPortGetLineOut(ch->port, &dtr, &rts);
-               if (dtr)
-                       flag |= TIOCM_DTR;
-               if (rts)
-                       flag |= TIOCM_RTS;
-               dtr = MoxaPortLineStatus(ch->port);
-               if (dtr & 1)
-                       flag |= TIOCM_CTS;
-               if (dtr & 2)
-                       flag |= TIOCM_DSR;
-               if (dtr & 4)
-                       flag |= TIOCM_CD;
-               return put_user(flag, (unsigned int *) arg);
-       case TIOCMBIS:
-               if(get_user(retval, (unsigned int *) arg))
-                       return -EFAULT;
-               MoxaPortGetLineOut(ch->port, &dtr, &rts);
-               if (retval & TIOCM_RTS)
-                       rts = 1;
-               if (retval & TIOCM_DTR)
-                       dtr = 1;
-               MoxaPortLineCtrl(ch->port, dtr, rts);
-               return (0);
-       case TIOCMBIC:
-               if(get_user(retval, (unsigned int *) arg))
-                       return -EFAULT;
-               MoxaPortGetLineOut(ch->port, &dtr, &rts);
-               if (retval & TIOCM_RTS)
-                       rts = 0;
-               if (retval & TIOCM_DTR)
-                       dtr = 0;
-               MoxaPortLineCtrl(ch->port, dtr, rts);
-               return (0);
-       case TIOCMSET:
-               if(get_user(retval, (unsigned long *) arg))
-                       return -EFAULT;
-               dtr = rts = 0;
-               if (retval & TIOCM_RTS)
-                       rts = 1;
-               if (retval & TIOCM_DTR)
-                       dtr = 1;
-               MoxaPortLineCtrl(ch->port, dtr, rts);
-               return (0);
        case TIOCGSERIAL:
                return (moxa_get_serial_info(ch, (struct serial_struct *) arg));
 
index 3f27b9082ec6deef8fcf6655799ea480742d6177..e4cf575fd079fca5b3daf23df5e366d2fc55f3c1 100644 (file)
@@ -350,8 +350,8 @@ static int mxser_get_serial_info(struct mxser_struct *, struct serial_struct *);
 static int mxser_set_serial_info(struct mxser_struct *, struct serial_struct *);
 static int mxser_get_lsr_info(struct mxser_struct *, unsigned int *);
 static void mxser_send_break(struct mxser_struct *, int);
-static int mxser_get_modem_info(struct mxser_struct *, unsigned int *);
-static int mxser_set_modem_info(struct mxser_struct *, unsigned int, unsigned int *);
+static int mxser_tiocmget(struct tty_struct *, struct file *);
+static int mxser_tiocmset(struct tty_struct *, struct file *, unsigned int, unsigned int);
 
 /*
  * The MOXA C168/C104 serial driver boot-time initialization code!
@@ -492,6 +492,8 @@ static struct tty_operations mxser_ops = {
        .stop = mxser_stop,
        .start = mxser_start,
        .hangup = mxser_hangup,
+       .tiocmget = mxser_tiocmget,
+       .tiocmset = mxser_tiocmset,
 };
 
 static int __init mxser_module_init(void)
@@ -1009,12 +1011,6 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
                tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) |
                                         (arg ? CLOCAL : 0));
                return (0);
-       case TIOCMGET:
-               return (mxser_get_modem_info(info, (unsigned int *) arg));
-       case TIOCMBIS:
-       case TIOCMBIC:
-       case TIOCMSET:
-               return (mxser_set_modem_info(info, cmd, (unsigned int *) arg));
        case TIOCGSERIAL:
                return (mxser_get_serial_info(info, (struct serial_struct *) arg));
        case TIOCSSERIAL:
@@ -2150,13 +2146,18 @@ static void mxser_send_break(struct mxser_struct *info, int duration)
        restore_flags(flags);
 }
 
-static int mxser_get_modem_info(struct mxser_struct *info,
-                               unsigned int *value)
+static int mxser_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
        unsigned char control, status;
        unsigned int result;
        unsigned long flags;
 
+       if (PORTNO(tty) == MXSER_PORTS)
+               return (-ENOIOCTLCMD);
+       if (tty->flags & (1 << TTY_IO_ERROR))
+               return (-EIO);
+
        control = info->MCR;
        save_flags(flags);
        cli();
@@ -2164,46 +2165,38 @@ static int mxser_get_modem_info(struct mxser_struct *info,
        if (status & UART_MSR_ANY_DELTA)
                mxser_check_modem_status(info, status);
        restore_flags(flags);
-       result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) |
+       return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) |
            ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) |
            ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) |
            ((status & UART_MSR_RI) ? TIOCM_RNG : 0) |
            ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) |
            ((status & UART_MSR_CTS) ? TIOCM_CTS : 0);
-       return put_user(result, value);
 }
 
-static int mxser_set_modem_info(struct mxser_struct *info, unsigned int cmd,
-                               unsigned int *value)
+static int mxser_tiocmset(struct tty_struct *tty, struct file *file,
+                         unsigned int set, unsigned int clear)
 {
+       struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
        unsigned int arg;
        unsigned long flags;
 
-       if(get_user(arg, value))
-               return -EFAULT;
-       switch (cmd) {
-       case TIOCMBIS:
-               if (arg & TIOCM_RTS)
-                       info->MCR |= UART_MCR_RTS;
-               if (arg & TIOCM_DTR)
-                       info->MCR |= UART_MCR_DTR;
-               break;
-       case TIOCMBIC:
-               if (arg & TIOCM_RTS)
-                       info->MCR &= ~UART_MCR_RTS;
-               if (arg & TIOCM_DTR)
-                       info->MCR &= ~UART_MCR_DTR;
-               break;
-       case TIOCMSET:
-               info->MCR = ((info->MCR & ~(UART_MCR_RTS | UART_MCR_DTR)) |
-                            ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0) |
-                            ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0));
-               break;
-       default:
-               return (-EINVAL);
-       }
+       if (PORTNO(tty) == MXSER_PORTS)
+               return (-ENOIOCTLCMD);
+       if (tty->flags & (1 << TTY_IO_ERROR))
+               return (-EIO);
+
        save_flags(flags);
        cli();
+       if (set & TIOCM_RTS)
+               info->MCR |= UART_MCR_RTS;
+       if (set & TIOCM_DTR)
+               info->MCR |= UART_MCR_DTR;
+
+       if (clear & TIOCM_RTS)
+               info->MCR &= ~UART_MCR_RTS;
+       if (clear & TIOCM_DTR)
+               info->MCR &= ~UART_MCR_DTR;
+
        outb(info->MCR, info->base + UART_MCR);
        restore_flags(flags);
        return (0);
index 3d3ad669da103b23e5b92c4de283996d1c71ad94..9b1e8ca9bee891f8b4541b1a932b334570769bc8 100644 (file)
@@ -173,6 +173,9 @@ static inline void txwinon(struct channel *ch);
 static inline void memoff(struct channel *ch);
 static inline void assertgwinon(struct channel *ch);
 static inline void assertmemoff(struct channel *ch);
+static int pcxe_tiocmget(struct tty_struct *tty, struct file *file);
+static int pcxe_tiocmset(struct tty_struct *tty, struct file *file,
+                        unsigned int set, unsigned int clear);
 
 #define TZ_BUFSZ 4096
 
@@ -1029,6 +1032,8 @@ static struct tty_operations pcxe_ops = {
        .stop = pcxe_stop,
        .start = pcxe_start,
        .hangup = pcxe_hangup,
+       .tiocmget = pcxe_tiocmget,
+       .tiocmset = pcxe_tiocmset,
 };
 
 /*
@@ -1983,6 +1988,89 @@ static void receive_data(struct channel *ch)
 }
 
 
+static int pcxe_tiocmget(struct tty_struct *tty, struct file *file)
+{
+       struct channel *ch = (struct channel *) tty->driver_data;
+       volatile struct board_chan *bc;
+       unsigned long flags;
+       int mflag = 0;
+
+       if(ch)
+               bc = ch->brdchan;
+       else {
+               printk("ch is NULL in %s!\n", __FUNCTION__);
+               return(-EINVAL);
+       }
+
+       save_flags(flags);
+       cli();
+       globalwinon(ch);
+       mstat = bc->mstat;
+       memoff(ch);
+       restore_flags(flags);
+
+       if(mstat & DTR)
+               mflag |= TIOCM_DTR;
+       if(mstat & RTS)
+               mflag |= TIOCM_RTS;
+       if(mstat & CTS)
+               mflag |= TIOCM_CTS;
+       if(mstat & ch->dsr)
+               mflag |= TIOCM_DSR;
+       if(mstat & RI)
+               mflag |= TIOCM_RI;
+       if(mstat & ch->dcd)
+               mflag |= TIOCM_CD;
+
+       return mflag;
+}
+
+
+static int pcxe_tiocmset(struct tty_struct *tty, struct file *file,
+                        unsigned int set, unsigned int clear)
+{
+       struct channel *ch = (struct channel *) tty->driver_data;
+       volatile struct board_chan *bc;
+       unsigned long flags;
+
+       if(ch)
+               bc = ch->brdchan;
+       else {
+               printk("ch is NULL in %s!\n", __FUNCTION__);
+               return(-EINVAL);
+       }
+
+       save_flags(flags);
+       cli();
+       /*
+        * I think this modemfake stuff is broken.  It doesn't
+        * correctly reflect the behaviour desired by the TIOCM*
+        * ioctls.  Therefore this is probably broken.
+        */
+       if (set & TIOCM_DTR) {
+               ch->modemfake |= DTR;
+               ch->modem |= DTR;
+       }
+       if (set & TIOCM_RTS) {
+               ch->modemfake |= RTS;
+               ch->modem |= RTS;
+       }
+
+       if (clear & TIOCM_DTR) {
+               ch->modemfake |= DTR;
+               ch->modem &= ~DTR;
+       }
+       if (clear & TIOCM_RTS) {
+               ch->modemfake |= RTS;
+               ch->modem &= ~RTS;
+       }
+       globalwinon(ch);
+       pcxxparam(tty,ch);
+       memoff(ch);
+       restore_flags(flags);
+}
+
+
 static int pcxe_ioctl(struct tty_struct *tty, struct file * file,
                    unsigned int cmd, unsigned long arg)
 {
@@ -2036,69 +2124,15 @@ static int pcxe_ioctl(struct tty_struct *tty, struct file * file,
                        return 0;
 
                case TIOCMODG:
-               case TIOCMGET:
-                       mflag = 0;
-
-                       cli();
-                       globalwinon(ch);
-                       mstat = bc->mstat;
-                       memoff(ch);
-                       restore_flags(flags);
-
-                       if(mstat & DTR)
-                               mflag |= TIOCM_DTR;
-                       if(mstat & RTS)
-                               mflag |= TIOCM_RTS;
-                       if(mstat & CTS)
-                               mflag |= TIOCM_CTS;
-                       if(mstat & ch->dsr)
-                               mflag |= TIOCM_DSR;
-                       if(mstat & RI)
-                               mflag |= TIOCM_RI;
-                       if(mstat & ch->dcd)
-                               mflag |= TIOCM_CD;
-
+                       mflag = pcxe_tiocmget(tty, file);
                        if (put_user(mflag, (unsigned int *) arg))
                                return -EFAULT;
                        break;
 
-               case TIOCMBIS:
-               case TIOCMBIC:
                case TIOCMODS:
-               case TIOCMSET:
                        if (get_user(mstat, (unsigned int *) arg))
                                return -EFAULT;
-
-                       mflag = 0;
-                       if(mstat & TIOCM_DTR)
-                               mflag |= DTR;
-                       if(mstat & TIOCM_RTS)
-                               mflag |= RTS;
-
-                       switch(cmd) {
-                               case TIOCMODS:
-                               case TIOCMSET:
-                                       ch->modemfake = DTR|RTS;
-                                       ch->modem = mflag;
-                                       break;
-
-                               case TIOCMBIS:
-                                       ch->modemfake |= mflag;
-                                       ch->modem |= mflag;
-                                       break;
-
-                               case TIOCMBIC:
-                                       ch->modemfake &= ~mflag;
-                                       ch->modem &= ~mflag;
-                                       break;
-                       }
-
-                       cli();
-                       globalwinon(ch);
-                       pcxxparam(tty,ch);
-                       memoff(ch);
-                       restore_flags(flags);
-                       break;
+                       return pcxe_tiocmset(tty, file, mstat, ~mstat);
 
                case TIOCSDTR:
                        cli();
index 96221c5601c3614bf543b0ca7b982fb8c33ea1f1..e5a8f39e2fd6c3e4cc5e32e29ce5b56742b03673 100644 (file)
@@ -1306,13 +1306,17 @@ static void rc_flush_buffer(struct tty_struct *tty)
                (tty->ldisc.write_wakeup)(tty);
 }
 
-static int rc_get_modem_info(struct riscom_port * port, unsigned int *value)
+static int rc_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct riscom_port *port = (struct riscom_port *)tty->driver_data;
        struct riscom_board * bp;
        unsigned char status;
        unsigned int result;
        unsigned long flags;
 
+       if (rc_paranoia_check(port, tty->name, __FUNCTION__))
+               return -ENODEV;
+
        bp = port_Board(port);
        save_flags(flags); cli();
        rc_out(bp, CD180_CAR, port_No(port));
@@ -1324,41 +1328,32 @@ static int rc_get_modem_info(struct riscom_port * port, unsigned int *value)
                | ((status & MSVR_CD)  ? TIOCM_CAR : 0)
                | ((status & MSVR_DSR) ? TIOCM_DSR : 0)
                | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
-       return put_user(result, value);
+       return result;
 }
 
-static int rc_set_modem_info(struct riscom_port * port, unsigned int cmd,
-                            unsigned int *value)
+static int rc_tiocmset(struct tty_struct *tty, struct file *file,
+                      unsigned int set, unsigned int clear)
 {
-       unsigned int arg;
+       struct riscom_port *port = (struct riscom_port *)tty->driver_data;
        unsigned long flags;
-       struct riscom_board *bp = port_Board(port);
+       struct riscom_board *bp;
+
+       if (rc_paranoia_check(port, tty->name, __FUNCTION__))
+               return -ENODEV;
+
+       bp = port_Board(port);
 
-       if (get_user(arg, value))
-               return -EFAULT;
-       switch (cmd) {
-        case TIOCMBIS: 
-               if (arg & TIOCM_RTS) 
-                       port->MSVR |= MSVR_RTS;
-               if (arg & TIOCM_DTR)
-                       bp->DTR &= ~(1u << port_No(port));
-               break;
-       case TIOCMBIC:
-               if (arg & TIOCM_RTS)
-                       port->MSVR &= ~MSVR_RTS;
-               if (arg & TIOCM_DTR)
-                       bp->DTR |= (1u << port_No(port));
-               break;
-       case TIOCMSET:
-               port->MSVR = (arg & TIOCM_RTS) ? (port->MSVR | MSVR_RTS) : 
-                                                (port->MSVR & ~MSVR_RTS);
-               bp->DTR = arg & TIOCM_DTR ? (bp->DTR &= ~(1u << port_No(port))) :
-                                           (bp->DTR |=  (1u << port_No(port)));
-               break;
-        default:
-               return -EINVAL;
-       }
        save_flags(flags); cli();
+       if (set & TIOCM_RTS)
+               port->MSVR |= MSVR_RTS;
+       if (set & TIOCM_DTR)
+               bp->DTR &= ~(1u << port_No(port));
+
+       if (clear & TIOCM_RTS)
+               port->MSVR &= ~MSVR_RTS;
+       if (clear & TIOCM_DTR)
+               bp->DTR |= (1u << port_No(port));
+
        rc_out(bp, CD180_CAR, port_No(port));
        rc_out(bp, CD180_MSVR, port->MSVR);
        rc_out(bp, RC_DTR, bp->DTR);
@@ -1485,12 +1480,6 @@ static int rc_ioctl(struct tty_struct * tty, struct file * filp,
                        ((tty->termios->c_cflag & ~CLOCAL) |
                        (arg ? CLOCAL : 0));
                break;
-        case TIOCMGET:
-               return rc_get_modem_info(port, (unsigned int *) arg);
-        case TIOCMBIS:
-        case TIOCMBIC:
-        case TIOCMSET:
-               return rc_set_modem_info(port, cmd, (unsigned int *) arg);
         case TIOCGSERIAL:      
                return rc_get_serial_info(port, (struct serial_struct *) arg);
         case TIOCSSERIAL:      
@@ -1677,6 +1666,8 @@ static struct tty_operations riscom_ops = {
        .stop = rc_stop,
        .start = rc_start,
        .hangup = rc_hangup,
+       .tiocmget = rc_tiocmget,
+       .tiocmset = rc_tiocmset,
 };
 
 static inline int rc_init_drivers(void)
index c0904c2bbe7134777f31eb80cb5b955a2b051105..1b51eecfb931ed2183c335be0d586cf34c308379 100644 (file)
@@ -1492,8 +1492,9 @@ check_and_exit:
 } /* set_serial_info */
 
 static int
-get_modem_info(struct cyclades_port * info, unsigned int *value)
+cy_tiocmget(struct tty_struct *tty, struct file *file)
 {
+  struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
   int channel;
   volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
   unsigned long flags;
@@ -1507,36 +1508,32 @@ get_modem_info(struct cyclades_port * info, unsigned int *value)
         status = base_addr[CyMSVR1] | base_addr[CyMSVR2];
     local_irq_restore(flags);
 
-    result =  ((status  & CyRTS) ? TIOCM_RTS : 0)
+    return    ((status  & CyRTS) ? TIOCM_RTS : 0)
             | ((status  & CyDTR) ? TIOCM_DTR : 0)
             | ((status  & CyDCD) ? TIOCM_CAR : 0)
             | ((status  & CyDSR) ? TIOCM_DSR : 0)
             | ((status  & CyCTS) ? TIOCM_CTS : 0);
-    return put_user(result,(unsigned int *) value);
-} /* get_modem_info */
+} /* cy_tiocmget */
 
 static int
-set_modem_info(struct cyclades_port * info, unsigned int cmd,
-                          unsigned int *value)
+cy_tiocmset(struct tty_struct *tty, struct file *file,
+           unsigned int set, unsigned int clear)
 {
+  struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
   int channel;
   volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
   unsigned long flags;
   unsigned int arg;
          
-    if (get_user(arg, (unsigned long *) value))
-       return -EFAULT;
     channel = info->line;
 
-    switch (cmd) {
-    case TIOCMBIS:
-       if (arg & TIOCM_RTS){
+       if (set & TIOCM_RTS){
            local_irq_save(flags);
                base_addr[CyCAR] = (u_char)channel;
                base_addr[CyMSVR1] = CyRTS;
            local_irq_restore(flags);
        }
-       if (arg & TIOCM_DTR){
+       if (set & TIOCM_DTR){
            local_irq_save(flags);
            base_addr[CyCAR] = (u_char)channel;
 /* CP('S');CP('2'); */
@@ -1547,15 +1544,14 @@ set_modem_info(struct cyclades_port * info, unsigned int cmd,
 #endif
            local_irq_restore(flags);
        }
-       break;
-    case TIOCMBIC:
-       if (arg & TIOCM_RTS){
+
+       if (clear & TIOCM_RTS){
            local_irq_save(flags);
                base_addr[CyCAR] = (u_char)channel;
                base_addr[CyMSVR1] = 0;
            local_irq_restore(flags);
        }
-       if (arg & TIOCM_DTR){
+       if (clear & TIOCM_DTR){
            local_irq_save(flags);
            base_addr[CyCAR] = (u_char)channel;
 /* CP('C');CP('2'); */
@@ -1566,44 +1562,7 @@ set_modem_info(struct cyclades_port * info, unsigned int cmd,
 #endif
            local_irq_restore(flags);
        }
-       break;
-    case TIOCMSET:
-       if (arg & TIOCM_RTS){
-           local_irq_save(flags);
-               base_addr[CyCAR] = (u_char)channel;
-               base_addr[CyMSVR1] = CyRTS;
-           local_irq_restore(flags);
-       }else{
-           local_irq_save(flags);
-               base_addr[CyCAR] = (u_char)channel;
-               base_addr[CyMSVR1] = 0;
-           local_irq_restore(flags);
-       }
-       if (arg & TIOCM_DTR){
-           local_irq_save(flags);
-           base_addr[CyCAR] = (u_char)channel;
-/* CP('S');CP('3'); */
-           base_addr[CyMSVR2] = CyDTR;
-#ifdef SERIAL_DEBUG_DTR
-            printk("cyc: %d: raising DTR\n", __LINE__);
-            printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
-#endif
-           local_irq_restore(flags);
-       }else{
-           local_irq_save(flags);
-           base_addr[CyCAR] = (u_char)channel;
-/* CP('C');CP('3'); */
-           base_addr[CyMSVR2] = 0;
-#ifdef SERIAL_DEBUG_DTR
-            printk("cyc: %d: dropping DTR\n", __LINE__);
-            printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
-#endif
-           local_irq_restore(flags);
-       }
-       break;
-    default:
-               return -EINVAL;
-        }
+
     return 0;
 } /* set_modem_info */
 
@@ -1777,11 +1736,6 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
             tty_wait_until_sent(tty,0);
             send_break(info, arg ? arg*(HZ/10) : HZ/4);
             break;
-        case TIOCMBIS:
-        case TIOCMBIC:
-        case TIOCMSET:
-            ret_val = set_modem_info(info, cmd, (unsigned int *) arg);
-            break;
 
 /* The following commands are incompletely implemented!!! */
         case TIOCGSOFTCAR:
@@ -1794,9 +1748,6 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
             tty->termios->c_cflag =
                     ((tty->termios->c_cflag & ~CLOCAL) | (val ? CLOCAL : 0));
             break;
-        case TIOCMGET:
-            ret_val = get_modem_info(info, (unsigned int *) arg);
-            break;
         case TIOCGSERIAL:
             ret_val = get_serial_info(info, (struct serial_struct *) arg);
             break;
@@ -2299,6 +2250,8 @@ static struct tty_operations cy_ops = {
        .stop = cy_stop,
        .start = cy_start,
        .hangup = cy_hangup,
+       .tiocmget = cy_tiocmget,
+       .tiocmset = cy_tiocmset,
 };
 /* The serial driver boot-time initialization code!
     Hardware I/O ports are mapped to character special devices on a
index 55e9b7663ff907cc1fbbab900bc25bd9c35d7219..cbc23701e88ee73253cea50325061451328e982e 100644 (file)
@@ -1653,13 +1653,17 @@ static void sx_flush_buffer(struct tty_struct *tty)
 }
 
 
-static int sx_get_modem_info(struct specialix_port * port, unsigned int *value)
+static int sx_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct specialix_port *port = (struct specialix_port *)tty->driver_data;
        struct specialix_board * bp;
        unsigned char status;
        unsigned int result;
        unsigned long flags;
 
+       if (sx_paranoia_check(port, tty->name, __FUNCTION__))
+               return -ENODEV;
+
        bp = port_Board(port);
        save_flags(flags); cli();
        sx_out(bp, CD186x_CAR, port_No(port));
@@ -1683,71 +1687,51 @@ static int sx_get_modem_info(struct specialix_port * port, unsigned int *value)
                          |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
                          |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
        }
-       put_user(result,(unsigned int *) value);
-       return 0;
+
+       return result;
 }
 
 
-static int sx_set_modem_info(struct specialix_port * port, unsigned int cmd,
-                             unsigned int *value)
+static int sx_tiocmset(struct tty_struct *tty, struct file *file,
+                      unsigned int set, unsigned int clear)
 {
+       struct specialix_port *port = (struct specialix_port *)tty->driver_data;
        int error;
        unsigned int arg;
        unsigned long flags;
-       struct specialix_board *bp = port_Board(port);
+       struct specialix_board *bp;
 
-       error = verify_area(VERIFY_READ, value, sizeof(int));
-       if (error) 
-               return error;
+       if (sx_paranoia_check(port, tty->name, __FUNCTION__))
+               return -ENODEV;
+
+       bp = port_Board(port);
 
-       get_user(arg, (unsigned long *) value);
-       switch (cmd) {
-       case TIOCMBIS: 
-          /*   if (arg & TIOCM_RTS) 
-                       port->MSVR |= MSVR_RTS; */
-          /*   if (arg & TIOCM_DTR)
-                       port->MSVR |= MSVR_DTR; */
-
-               if (SX_CRTSCTS(port->tty)) {
-                       if (arg & TIOCM_RTS)
-                               port->MSVR |= MSVR_DTR; 
-               } else {
-                       if (arg & TIOCM_DTR)
-                               port->MSVR |= MSVR_DTR; 
-               }            
-               break;
-       case TIOCMBIC:
-         /*    if (arg & TIOCM_RTS)
-                       port->MSVR &= ~MSVR_RTS; */
-         /*    if (arg & TIOCM_DTR)
-                       port->MSVR &= ~MSVR_DTR; */
-               if (SX_CRTSCTS(port->tty)) {
-                       if (arg & TIOCM_RTS)
-                               port->MSVR &= ~MSVR_DTR;
-               } else {
-                       if (arg & TIOCM_DTR)
-                               port->MSVR &= ~MSVR_DTR;
-               }
-               break;
-       case TIOCMSET:
-         /* port->MSVR = (arg & TIOCM_RTS) ? (port->MSVR | MSVR_RTS) : 
-                                                (port->MSVR & ~MSVR_RTS); */
-         /* port->MSVR = (arg & TIOCM_DTR) ? (port->MSVR | MSVR_DTR) : 
-                                                (port->MSVR & ~MSVR_DTR); */
-               if (SX_CRTSCTS(port->tty)) {
-                       port->MSVR = (arg & TIOCM_RTS) ? 
-                                                (port->MSVR |  MSVR_DTR) : 
-                                                (port->MSVR & ~MSVR_DTR);
-               } else {
-                       port->MSVR = (arg & TIOCM_DTR) ?
-                                                (port->MSVR |  MSVR_DTR):
-                                                (port->MSVR & ~MSVR_DTR);
-               }
-               break;
-       default:
-               return -EINVAL;
-       }
        save_flags(flags); cli();
+   /*  if (set & TIOCM_RTS)
+               port->MSVR |= MSVR_RTS; */
+   /*   if (set & TIOCM_DTR)
+               port->MSVR |= MSVR_DTR; */
+
+       if (SX_CRTSCTS(port->tty)) {
+               if (set & TIOCM_RTS)
+                       port->MSVR |= MSVR_DTR;
+       } else {
+               if (set & TIOCM_DTR)
+                       port->MSVR |= MSVR_DTR;
+       }
+
+  /*   if (clear & TIOCM_RTS)
+               port->MSVR &= ~MSVR_RTS; */
+  /*    if (clear & TIOCM_DTR)
+               port->MSVR &= ~MSVR_DTR; */
+       if (SX_CRTSCTS(port->tty)) {
+               if (clear & TIOCM_RTS)
+                       port->MSVR &= ~MSVR_DTR;
+       } else {
+               if (clear & TIOCM_DTR)
+                       port->MSVR &= ~MSVR_DTR;
+       }
+
        sx_out(bp, CD186x_CAR, port_No(port));
        sx_out(bp, CD186x_MSVR, port->MSVR);
        restore_flags(flags);
@@ -1897,16 +1881,6 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp,
                        ((tty->termios->c_cflag & ~CLOCAL) |
                        (arg ? CLOCAL : 0));
                return 0;
-        case TIOCMGET:
-               error = verify_area(VERIFY_WRITE, (void *) arg,
-                                   sizeof(unsigned int));
-               if (error)
-                       return error;
-               return sx_get_modem_info(port, (unsigned int *) arg);
-        case TIOCMBIS:
-        case TIOCMBIC:
-        case TIOCMSET:
-               return sx_set_modem_info(port, cmd, (unsigned int *) arg);
         case TIOCGSERIAL:      
                return sx_get_serial_info(port, (struct serial_struct *) arg);
         case TIOCSSERIAL:      
@@ -2116,6 +2090,8 @@ static struct tty_operations sx_ops = {
        .stop = sx_stop,
        .start = sx_start,
        .hangup = sx_hangup,
+       .tiocmget = sx_tiocmget,
+       .tiocmset = sx_tiocmset,
 };
 
 static int sx_init_drivers(void)
index cec4bd6c2b4562dba1bb07228451b59387a5272f..d45619f3b563bfd27b97d236ca14f4e5a15619f9 100644 (file)
@@ -1752,8 +1752,9 @@ static void aurora_flush_buffer(struct tty_struct *tty)
 #endif
 }
 
-static int aurora_get_modem_info(struct Aurora_port * port, unsigned int *value)
+static int aurora_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
        struct Aurora_board * bp;
        unsigned char status,chip;
        unsigned int result;
@@ -1762,6 +1763,9 @@ static int aurora_get_modem_info(struct Aurora_port * port, unsigned int *value)
 #ifdef AURORA_DEBUG
        printk("aurora_get_modem_info: start\n");
 #endif
+       if ((aurora_paranoia_check(port, tty->name, __FUNCTION__))
+               return -ENODEV;
+
        chip = AURORA_CD180(port_No(port));
 
        bp = port_Board(port);
@@ -1782,16 +1786,16 @@ static int aurora_get_modem_info(struct Aurora_port * port, unsigned int *value)
                | ((status & MSVR_DSR) ? TIOCM_DSR : 0)
                | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
 
-       put_user(result,(unsigned long *) value);
 #ifdef AURORA_DEBUG
        printk("aurora_get_modem_info: end\n");
 #endif
-       return 0;
+       return result;
 }
 
-static int aurora_set_modem_info(struct Aurora_port * port, unsigned int cmd,
-                                unsigned int *value)
+static int aurora_tiocmset(struct tty_struct *tty, struct file *file,
+                          unsigned int set, unsigned int clear)
 {
+       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
        unsigned int arg;
        unsigned long flags;
        struct Aurora_board *bp = port_Board(port);
@@ -1800,33 +1804,20 @@ static int aurora_set_modem_info(struct Aurora_port * port, unsigned int cmd,
 #ifdef AURORA_DEBUG
        printk("aurora_set_modem_info: start\n");
 #endif
-       if (get_user(arg, value))
-               return -EFAULT;
+       if ((aurora_paranoia_check(port, tty->name, __FUNCTION__))
+               return -ENODEV;
+
        chip = AURORA_CD180(port_No(port));
-       switch (cmd) {
-        case TIOCMBIS: 
-               if (arg & TIOCM_RTS) 
-                       port->MSVR |= bp->RTS;
-               if (arg & TIOCM_DTR)
-                       port->MSVR |= bp->DTR;
-               break;
-       case TIOCMBIC:
-               if (arg & TIOCM_RTS)
-                       port->MSVR &= ~bp->RTS;
-               if (arg & TIOCM_DTR)
-                       port->MSVR &= ~bp->DTR;
-               break;
-       case TIOCMSET:
-               port->MSVR = (arg & TIOCM_RTS) ? (port->MSVR | bp->RTS) : 
-                                                (port->MSVR & ~bp->RTS);
-               port->MSVR = (arg & TIOCM_DTR) ? (port->MSVR | bp->RTS) :
-                                                (port->MSVR & ~bp->RTS);
-               break;
-        default:
-               return -EINVAL;
-       };
 
        save_flags(flags); cli();
+       if (set & TIOCM_RTS)
+               port->MSVR |= bp->RTS;
+       if (set & TIOCM_DTR)
+               port->MSVR |= bp->DTR;
+       if (clear & TIOCM_RTS)
+               port->MSVR &= ~bp->RTS;
+       if (clear & TIOCM_DTR)
+               port->MSVR &= ~bp->DTR;
 
        sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]);
        udelay(1);
@@ -1993,16 +1984,6 @@ static int aurora_ioctl(struct tty_struct * tty, struct file * filp,
                        ((tty->termios->c_cflag & ~CLOCAL) |
                         (arg ? CLOCAL : 0));
                return 0;
-       case TIOCMGET:
-               retval = verify_area(VERIFY_WRITE, (void *) arg,
-                                   sizeof(unsigned int));
-               if (retval)
-                       return retval;
-               return aurora_get_modem_info(port, (unsigned int *) arg);
-       case TIOCMBIS:
-       case TIOCMBIC:
-       case TIOCMSET:
-               return aurora_set_modem_info(port, cmd, (unsigned int *) arg);
        case TIOCGSERIAL:       
                return aurora_get_serial_info(port, (struct serial_struct *) arg);
        case TIOCSSERIAL:       
@@ -2268,6 +2249,8 @@ static struct tty_operations aurora_ops = {
        .stop = aurora_stop,
        .start = aurora_start,
        .hangup = aurora_hangup,
+       .tiocmget = aurora_tiocmget,
+       .tiocmset = aurora_tiocmset,
 };
 
 static int aurora_init_drivers(void)
index 96b54b2304262f261933d5512a2f31df2df6792f..c8fa14eb7727a73484513dc74fbf505e07a06b4c 100644 (file)
@@ -1282,12 +1282,19 @@ static int get_lsr_info(struct async_struct * info, unsigned int *value)
 }
 #endif
 
-static int get_modem_info(ser_info_t *info, unsigned int *value)
+static int rs_360_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
        unsigned int result = 0;
 #ifdef modem_control
        unsigned char control, status;
 
+       if (serial_paranoia_check(info, tty->name, __FUNCTION__))
+               return -ENODEV;
+
+       if (tty->flags & (1 << TTY_IO_ERROR))
+               return -EIO;
+
        control = info->MCR;
        local_irq_disable();
        status = serial_in(info, UART_MSR);
@@ -1303,63 +1310,42 @@ static int get_modem_info(ser_info_t *info, unsigned int *value)
                | ((status  & UART_MSR_DSR) ? TIOCM_DSR : 0)
                | ((status  & UART_MSR_CTS) ? TIOCM_CTS : 0);
 #endif
-       /* return put_user(result,value); */
-       put_user(result,value);
-       return (0);
+       return result;
 }
 
-static int set_modem_info(ser_info_t *info, unsigned int cmd,
-                         unsigned int *value)
+static int rs_360_tiocmset(struct tty_struct *tty, struct file *file,
+                          unsigned int set, unsigned int clear)
 {
-       int error;
-       unsigned int arg; 
-
-       error = get_user(arg,value);
-       if (error)
-               return error;
 #ifdef modem_control
-       switch (cmd) {
-       case TIOCMBIS: 
-               if (arg & TIOCM_RTS)
-                       info->MCR |= UART_MCR_RTS;
-               if (arg & TIOCM_DTR)
-                       info->MCR |= UART_MCR_DTR;
-#ifdef TIOCM_OUT1
-               if (arg & TIOCM_OUT1)
-                       info->MCR |= UART_MCR_OUT1;
-               if (arg & TIOCM_OUT2)
-                       info->MCR |= UART_MCR_OUT2;
-#endif
-               break;
-       case TIOCMBIC:
-               if (arg & TIOCM_RTS)
-                       info->MCR &= ~UART_MCR_RTS;
-               if (arg & TIOCM_DTR)
-                       info->MCR &= ~UART_MCR_DTR;
-#ifdef TIOCM_OUT1
-               if (arg & TIOCM_OUT1)
-                       info->MCR &= ~UART_MCR_OUT1;
-               if (arg & TIOCM_OUT2)
-                       info->MCR &= ~UART_MCR_OUT2;
-#endif
-               break;
-       case TIOCMSET:
-               info->MCR = ((info->MCR & ~(UART_MCR_RTS |
-#ifdef TIOCM_OUT1
-                                           UART_MCR_OUT1 |
-                                           UART_MCR_OUT2 |
-#endif
-                                           UART_MCR_DTR))
-                            | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
+       unsigned int arg;
+
+       if (serial_paranoia_check(info, tty->name, __FUNCTION__))
+               return -ENODEV;
+
+       if (tty->flags & (1 << TTY_IO_ERROR))
+               return -EIO;
+
+       if (set & TIOCM_RTS)
+               info->mcr |= UART_MCR_RTS;
+       if (set & TIOCM_DTR)
+               info->mcr |= UART_MCR_DTR;
+       if (clear & TIOCM_RTS)
+               info->MCR &= ~UART_MCR_RTS;
+       if (clear & TIOCM_DTR)
+               info->MCR &= ~UART_MCR_DTR;
+
 #ifdef TIOCM_OUT1
-                            | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0)
-                            | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0)
+       if (set & TIOCM_OUT1)
+               info->MCR |= UART_MCR_OUT1;
+       if (set & TIOCM_OUT2)
+               info->MCR |= UART_MCR_OUT2;
+       if (clear & TIOCM_OUT1)
+               info->MCR &= ~UART_MCR_OUT1;
+       if (clear & TIOCM_OUT2)
+               info->MCR &= ~UART_MCR_OUT2;
 #endif
-                            | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0));
-               break;
-       default:
-               return -EINVAL;
-       }
+
        local_irq_disable();
        serial_out(info, UART_MCR, info->MCR);
        local_irq_enable();
@@ -1506,12 +1492,6 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file,
                                ((tty->termios->c_cflag & ~CLOCAL) |
                                 (arg ? CLOCAL : 0));
                        return 0;
-               case TIOCMGET:
-                       return get_modem_info(info, (unsigned int *) arg);
-               case TIOCMBIS:
-               case TIOCMBIC:
-               case TIOCMSET:
-                       return set_modem_info(info, cmd, (unsigned int *) arg);
 #ifdef maybe
                case TIOCSERGETLSR: /* Get line status register */
                        return get_lsr_info(info, (unsigned int *) arg);
@@ -2513,6 +2493,8 @@ static struct tty_operations rs_360_ops = {
        .hangup = rs_360_hangup,
        /* .wait_until_sent = rs_360_wait_until_sent, */
        /* .read_proc = rs_360_read_proc, */
+       .tiocmget = rs_360_tiocmget,
+       .tiocmset = rs_360_tiocmset,
 };
 
 /* int __init rs_360_init(void) */
index 8756c074a0751d02ef8d4a462db32fa332d2ea0c..5a2675da5b1f100202d088672ff98ac9bf1f2eda 100644 (file)
@@ -1176,11 +1176,21 @@ static int get_lsr_info(struct dec_serial * info, unsigned int *value)
        return 0;
 }
 
-static int get_modem_info(struct dec_serial *info, unsigned int *value)
+static int rs_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct dec_serial * info = (struct dec_serial *)tty->driver_data;
        unsigned char control, status_a, status_b;
        unsigned int result;
 
+       if (info->hook)
+               return -ENODEV;
+
+       if (serial_paranoia_check(info, tty->name, __FUNCTION__))
+               return -ENODEV;
+
+       if (tty->flags & (1 << TTY_IO_ERROR))
+               return -EIO;
+
        if (info->zs_channel == info->zs_chan_a)
                result = 0;
        else {
@@ -1196,41 +1206,37 @@ static int get_modem_info(struct dec_serial *info, unsigned int *value)
                        | ((status_a & SYNC_HUNT) ? TIOCM_DSR: 0)
                        | ((status_b & CTS) ? TIOCM_CTS: 0);
        }
-       put_user(result, value);
-       return 0;
+       return result;
 }
 
-static int set_modem_info(struct dec_serial *info, unsigned int cmd,
-                         unsigned int *value)
+static int rs_tiocmset(struct tty_struct *tty, struct file *file,
+                      unsigned int set, unsigned int clear)
 {
+       struct dec_serial * info = (struct dec_serial *)tty->driver_data;
        int error;
        unsigned int arg, bits;
 
-       error = verify_area(VERIFY_READ, value, sizeof(int));
-       if (error)
-               return error;
+       if (info->hook)
+               return -ENODEV;
+
+       if (serial_paranoia_check(info, tty->name, __FUNCTION__))
+               return -ENODEV;
+
+       if (tty->flags & (1 << TTY_IO_ERROR))
+               return -EIO;
 
        if (info->zs_channel == info->zs_chan_a)
                return 0;
 
-       get_user(arg, value);
-       bits = (arg & TIOCM_RTS? RTS: 0) + (arg & TIOCM_DTR? DTR: 0);
        cli();
-       switch (cmd) {
-       case TIOCMBIS:
-               info->zs_chan_a->curregs[5] |= bits;
-               break;
-       case TIOCMBIC:
-               info->zs_chan_a->curregs[5] &= ~bits;
-               break;
-       case TIOCMSET:
-               info->zs_chan_a->curregs[5] = 
-                       (info->zs_chan_a->curregs[5] & ~(DTR | RTS)) | bits;
-               break;
-       default:
-               sti();
-               return -EINVAL;
-       }
+       if (set & TIOCM_RTS)
+               info->zs_chan_a->curregs[5] |= RTS;
+       if (set & TIOCM_DTR)
+               info->zs_chan_a->curregs[5] |= DTR;
+       if (clear & TIOCM_RTS)
+               info->zs_chan_a->curregs[5] &= ~RTS;
+       if (clear & TIOCM_DTR)
+               info->zs_chan_a->curregs[5] &= ~DTR;
        write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]);
        sti();
        return 0;
@@ -1278,16 +1284,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
        }
        
        switch (cmd) {
-               case TIOCMGET:
-                       error = verify_area(VERIFY_WRITE, (void *) arg,
-                               sizeof(unsigned int));
-                       if (error)
-                               return error;
-                       return get_modem_info(info, (unsigned int *) arg);
-               case TIOCMBIS:
-               case TIOCMBIC:
-               case TIOCMSET:
-                       return set_modem_info(info, cmd, (unsigned int *) arg);
                case TIOCGSERIAL:
                        error = verify_area(VERIFY_WRITE, (void *) arg,
                                                sizeof(struct serial_struct));
@@ -1816,6 +1812,8 @@ static struct tty_operations serial_ops = {
        .hangup = rs_hangup,
        .break_ctl = rs_break,
        .wait_until_sent = rs_wait_until_sent,
+       .tiocmget = rs_tiocmget,
+       .tiocmset = rs_tiocmset,
 };
 
 /* zs_init inits the driver */