aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/synclink.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/synclink.c')
-rw-r--r--drivers/char/synclink.c73
1 files changed, 34 insertions, 39 deletions
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index a2a58004e188..3a6824f12be2 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -2925,6 +2925,38 @@ static int mgsl_break(struct tty_struct *tty, int break_state)
2925 2925
2926} /* end of mgsl_break() */ 2926} /* end of mgsl_break() */
2927 2927
2928/*
2929 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
2930 * Return: write counters to the user passed counter struct
2931 * NB: both 1->0 and 0->1 transitions are counted except for
2932 * RI where only 0->1 is counted.
2933 */
2934static int msgl_get_icount(struct tty_struct *tty,
2935 struct serial_icounter_struct *icount)
2936
2937{
2938 struct mgsl_struct * info = tty->driver_data;
2939 struct mgsl_icount cnow; /* kernel counter temps */
2940 unsigned long flags;
2941
2942 spin_lock_irqsave(&info->irq_spinlock,flags);
2943 cnow = info->icount;
2944 spin_unlock_irqrestore(&info->irq_spinlock,flags);
2945
2946 icount->cts = cnow.cts;
2947 icount->dsr = cnow.dsr;
2948 icount->rng = cnow.rng;
2949 icount->dcd = cnow.dcd;
2950 icount->rx = cnow.rx;
2951 icount->tx = cnow.tx;
2952 icount->frame = cnow.frame;
2953 icount->overrun = cnow.overrun;
2954 icount->parity = cnow.parity;
2955 icount->brk = cnow.brk;
2956 icount->buf_overrun = cnow.buf_overrun;
2957 return 0;
2958}
2959
2928/* mgsl_ioctl() Service an IOCTL request 2960/* mgsl_ioctl() Service an IOCTL request
2929 * 2961 *
2930 * Arguments: 2962 * Arguments:
@@ -2949,7 +2981,7 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file,
2949 return -ENODEV; 2981 return -ENODEV;
2950 2982
2951 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && 2983 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
2952 (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { 2984 (cmd != TIOCMIWAIT)) {
2953 if (tty->flags & (1 << TTY_IO_ERROR)) 2985 if (tty->flags & (1 << TTY_IO_ERROR))
2954 return -EIO; 2986 return -EIO;
2955 } 2987 }
@@ -2959,11 +2991,7 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file,
2959 2991
2960static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg) 2992static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg)
2961{ 2993{
2962 int error;
2963 struct mgsl_icount cnow; /* kernel counter temps */
2964 void __user *argp = (void __user *)arg; 2994 void __user *argp = (void __user *)arg;
2965 struct serial_icounter_struct __user *p_cuser; /* user space */
2966 unsigned long flags;
2967 2995
2968 switch (cmd) { 2996 switch (cmd) {
2969 case MGSL_IOCGPARAMS: 2997 case MGSL_IOCGPARAMS:
@@ -2992,40 +3020,6 @@ static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigne
2992 case TIOCMIWAIT: 3020 case TIOCMIWAIT:
2993 return modem_input_wait(info,(int)arg); 3021 return modem_input_wait(info,(int)arg);
2994 3022
2995 /*
2996 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
2997 * Return: write counters to the user passed counter struct
2998 * NB: both 1->0 and 0->1 transitions are counted except for
2999 * RI where only 0->1 is counted.
3000 */
3001 case TIOCGICOUNT:
3002 spin_lock_irqsave(&info->irq_spinlock,flags);
3003 cnow = info->icount;
3004 spin_unlock_irqrestore(&info->irq_spinlock,flags);
3005 p_cuser = argp;
3006 PUT_USER(error,cnow.cts, &p_cuser->cts);
3007 if (error) return error;
3008 PUT_USER(error,cnow.dsr, &p_cuser->dsr);
3009 if (error) return error;
3010 PUT_USER(error,cnow.rng, &p_cuser->rng);
3011 if (error) return error;
3012 PUT_USER(error,cnow.dcd, &p_cuser->dcd);
3013 if (error) return error;
3014 PUT_USER(error,cnow.rx, &p_cuser->rx);
3015 if (error) return error;
3016 PUT_USER(error,cnow.tx, &p_cuser->tx);
3017 if (error) return error;
3018 PUT_USER(error,cnow.frame, &p_cuser->frame);
3019 if (error) return error;
3020 PUT_USER(error,cnow.overrun, &p_cuser->overrun);
3021 if (error) return error;
3022 PUT_USER(error,cnow.parity, &p_cuser->parity);
3023 if (error) return error;
3024 PUT_USER(error,cnow.brk, &p_cuser->brk);
3025 if (error) return error;
3026 PUT_USER(error,cnow.buf_overrun, &p_cuser->buf_overrun);
3027 if (error) return error;
3028 return 0;
3029 default: 3023 default:
3030 return -ENOIOCTLCMD; 3024 return -ENOIOCTLCMD;
3031 } 3025 }
@@ -4328,6 +4322,7 @@ static const struct tty_operations mgsl_ops = {
4328 .hangup = mgsl_hangup, 4322 .hangup = mgsl_hangup,
4329 .tiocmget = tiocmget, 4323 .tiocmget = tiocmget,
4330 .tiocmset = tiocmset, 4324 .tiocmset = tiocmset,
4325 .get_icount = msgl_get_icount,
4331 .proc_fops = &mgsl_proc_fops, 4326 .proc_fops = &mgsl_proc_fops,
4332}; 4327};
4333 4328