diff options
Diffstat (limited to 'drivers/char/synclink.c')
-rw-r--r-- | drivers/char/synclink.c | 73 |
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 | */ | ||
2934 | static 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 | ||
2960 | static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg) | 2992 | static 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 | ||