Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6
[pandora-kernel.git] / drivers / char / ip2 / ip2main.c
index 64a439c..fcd02ba 100644 (file)
@@ -184,6 +184,8 @@ static void ip2_hangup(PTTY);
 static int  ip2_tiocmget(struct tty_struct *tty, struct file *file);
 static int  ip2_tiocmset(struct tty_struct *tty, struct file *file,
                         unsigned int set, unsigned int clear);
+static int ip2_get_icount(struct tty_struct *tty,
+               struct serial_icounter_struct *icount);
 
 static void set_irq(int, int);
 static void ip2_interrupt_bh(struct work_struct *work);
@@ -456,6 +458,7 @@ static const struct tty_operations ip2_ops = {
        .hangup          = ip2_hangup,
        .tiocmget        = ip2_tiocmget,
        .tiocmset        = ip2_tiocmset,
+       .get_icount      = ip2_get_icount,
        .proc_fops       = &ip2_proc_fops,
 };
 
@@ -2130,7 +2133,6 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
        i2ChanStrPtr pCh = DevTable[tty->index];
        i2eBordStrPtr pB;
        struct async_icount cprev, cnow;        /* kernel counter temps */
-       struct serial_icounter_struct __user *p_cuser;
        int rc = 0;
        unsigned long flags;
        void __user *argp = (void __user *)arg;
@@ -2298,34 +2300,6 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
                return rc;
                break;
 
-       /*
-        * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
-        * Return: write counters to the user passed counter struct
-        * NB: both 1->0 and 0->1 transitions are counted except for RI where
-        * only 0->1 is counted. The controller is quite capable of counting
-        * both, but this done to preserve compatibility with the standard
-        * serial driver.
-        */
-       case TIOCGICOUNT:
-               ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );
-
-               write_lock_irqsave(&pB->read_fifo_spinlock, flags);
-               cnow = pCh->icount;
-               write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
-               p_cuser = argp;
-               rc = put_user(cnow.cts, &p_cuser->cts);
-               rc = put_user(cnow.dsr, &p_cuser->dsr);
-               rc = put_user(cnow.rng, &p_cuser->rng);
-               rc = put_user(cnow.dcd, &p_cuser->dcd);
-               rc = put_user(cnow.rx, &p_cuser->rx);
-               rc = put_user(cnow.tx, &p_cuser->tx);
-               rc = put_user(cnow.frame, &p_cuser->frame);
-               rc = put_user(cnow.overrun, &p_cuser->overrun);
-               rc = put_user(cnow.parity, &p_cuser->parity);
-               rc = put_user(cnow.brk, &p_cuser->brk);
-               rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
-               break;
-
        /*
         * The rest are not supported by this driver. By returning -ENOIOCTLCMD they
         * will be passed to the line discipline for it to handle.
@@ -2350,6 +2324,46 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
        return rc;
 }
 
+static int ip2_get_icount(struct tty_struct *tty,
+               struct serial_icounter_struct *icount)
+{
+       i2ChanStrPtr pCh = DevTable[tty->index];
+       i2eBordStrPtr pB;
+       struct async_icount cnow;       /* kernel counter temp */
+       unsigned long flags;
+
+       if ( pCh == NULL )
+               return -ENODEV;
+
+       pB = pCh->pMyBord;
+
+       /*
+        * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+        * Return: write counters to the user passed counter struct
+        * NB: both 1->0 and 0->1 transitions are counted except for RI where
+        * only 0->1 is counted. The controller is quite capable of counting
+        * both, but this done to preserve compatibility with the standard
+        * serial driver.
+        */
+
+       write_lock_irqsave(&pB->read_fifo_spinlock, flags);
+       cnow = pCh->icount;
+       write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
+
+       icount->cts = cnow.cts;
+       icount->dsr = cnow.dsr;
+       icount->rng = cnow.rng;
+       icount->dcd = cnow.dcd;
+       icount->rx = cnow.rx;
+       icount->tx = cnow.tx;
+       icount->frame = cnow.frame;
+       icount->overrun = cnow.overrun;
+       icount->parity = cnow.parity;
+       icount->brk = cnow.brk;
+       icount->buf_overrun = cnow.buf_overrun;
+       return 0;
+}
+
 /******************************************************************************/
 /* Function:   GetSerialInfo()                                                */
 /* Parameters: Pointer to channel structure                                   */