diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/amiserial.c | 56 | ||||
-rw-r--r-- | drivers/char/cyclades.c | 49 | ||||
-rw-r--r-- | drivers/char/ip2/ip2main.c | 72 | ||||
-rw-r--r-- | drivers/char/mxser.c | 62 | ||||
-rw-r--r-- | drivers/char/nozomi.c | 37 | ||||
-rw-r--r-- | drivers/char/pcmcia/synclink_cs.c | 60 | ||||
-rw-r--r-- | drivers/char/synclink.c | 73 | ||||
-rw-r--r-- | drivers/char/synclink_gt.c | 55 | ||||
-rw-r--r-- | drivers/char/synclinkmp.c | 61 | ||||
-rw-r--r-- | drivers/serial/68360serial.c | 51 |
10 files changed, 296 insertions, 280 deletions
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index a11c8c9ca3d4..b0a70461a12c 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -1263,6 +1263,36 @@ static int rs_break(struct tty_struct *tty, int break_state) | |||
1263 | return 0; | 1263 | return 0; |
1264 | } | 1264 | } |
1265 | 1265 | ||
1266 | /* | ||
1267 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
1268 | * Return: write counters to the user passed counter struct | ||
1269 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
1270 | * RI where only 0->1 is counted. | ||
1271 | */ | ||
1272 | static int rs_get_icount(struct tty_struct *tty, | ||
1273 | struct serial_icounter_struct *icount) | ||
1274 | { | ||
1275 | struct async_struct *info = tty->driver_data; | ||
1276 | struct async_icount cnow; | ||
1277 | unsigned long flags; | ||
1278 | |||
1279 | local_irq_save(flags); | ||
1280 | cnow = info->state->icount; | ||
1281 | local_irq_restore(flags); | ||
1282 | icount->cts = cnow.cts; | ||
1283 | icount->dsr = cnow.dsr; | ||
1284 | icount->rng = cnow.rng; | ||
1285 | icount->dcd = cnow.dcd; | ||
1286 | icount->rx = cnow.rx; | ||
1287 | icount->tx = cnow.tx; | ||
1288 | icount->frame = cnow.frame; | ||
1289 | icount->overrun = cnow.overrun; | ||
1290 | icount->parity = cnow.parity; | ||
1291 | icount->brk = cnow.brk; | ||
1292 | icount->buf_overrun = cnow.buf_overrun; | ||
1293 | |||
1294 | return 0; | ||
1295 | } | ||
1266 | 1296 | ||
1267 | static int rs_ioctl(struct tty_struct *tty, struct file * file, | 1297 | static int rs_ioctl(struct tty_struct *tty, struct file * file, |
1268 | unsigned int cmd, unsigned long arg) | 1298 | unsigned int cmd, unsigned long arg) |
@@ -1332,31 +1362,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, | |||
1332 | } | 1362 | } |
1333 | /* NOTREACHED */ | 1363 | /* NOTREACHED */ |
1334 | 1364 | ||
1335 | /* | ||
1336 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
1337 | * Return: write counters to the user passed counter struct | ||
1338 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
1339 | * RI where only 0->1 is counted. | ||
1340 | */ | ||
1341 | case TIOCGICOUNT: | ||
1342 | local_irq_save(flags); | ||
1343 | cnow = info->state->icount; | ||
1344 | local_irq_restore(flags); | ||
1345 | icount.cts = cnow.cts; | ||
1346 | icount.dsr = cnow.dsr; | ||
1347 | icount.rng = cnow.rng; | ||
1348 | icount.dcd = cnow.dcd; | ||
1349 | icount.rx = cnow.rx; | ||
1350 | icount.tx = cnow.tx; | ||
1351 | icount.frame = cnow.frame; | ||
1352 | icount.overrun = cnow.overrun; | ||
1353 | icount.parity = cnow.parity; | ||
1354 | icount.brk = cnow.brk; | ||
1355 | icount.buf_overrun = cnow.buf_overrun; | ||
1356 | |||
1357 | if (copy_to_user(argp, &icount, sizeof(icount))) | ||
1358 | return -EFAULT; | ||
1359 | return 0; | ||
1360 | case TIOCSERGWILD: | 1365 | case TIOCSERGWILD: |
1361 | case TIOCSERSWILD: | 1366 | case TIOCSERSWILD: |
1362 | /* "setserial -W" is called in Debian boot */ | 1367 | /* "setserial -W" is called in Debian boot */ |
@@ -1958,6 +1963,7 @@ static const struct tty_operations serial_ops = { | |||
1958 | .wait_until_sent = rs_wait_until_sent, | 1963 | .wait_until_sent = rs_wait_until_sent, |
1959 | .tiocmget = rs_tiocmget, | 1964 | .tiocmget = rs_tiocmget, |
1960 | .tiocmset = rs_tiocmset, | 1965 | .tiocmset = rs_tiocmset, |
1966 | .get_icount = rs_get_icount, | ||
1961 | .proc_fops = &rs_proc_fops, | 1967 | .proc_fops = &rs_proc_fops, |
1962 | }; | 1968 | }; |
1963 | 1969 | ||
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 27aad9422332..4f152c28f40e 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -2790,29 +2790,6 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
2790 | * NB: both 1->0 and 0->1 transitions are counted except for | 2790 | * NB: both 1->0 and 0->1 transitions are counted except for |
2791 | * RI where only 0->1 is counted. | 2791 | * RI where only 0->1 is counted. |
2792 | */ | 2792 | */ |
2793 | case TIOCGICOUNT: { | ||
2794 | struct serial_icounter_struct sic = { }; | ||
2795 | |||
2796 | spin_lock_irqsave(&info->card->card_lock, flags); | ||
2797 | cnow = info->icount; | ||
2798 | spin_unlock_irqrestore(&info->card->card_lock, flags); | ||
2799 | |||
2800 | sic.cts = cnow.cts; | ||
2801 | sic.dsr = cnow.dsr; | ||
2802 | sic.rng = cnow.rng; | ||
2803 | sic.dcd = cnow.dcd; | ||
2804 | sic.rx = cnow.rx; | ||
2805 | sic.tx = cnow.tx; | ||
2806 | sic.frame = cnow.frame; | ||
2807 | sic.overrun = cnow.overrun; | ||
2808 | sic.parity = cnow.parity; | ||
2809 | sic.brk = cnow.brk; | ||
2810 | sic.buf_overrun = cnow.buf_overrun; | ||
2811 | |||
2812 | if (copy_to_user(argp, &sic, sizeof(sic))) | ||
2813 | ret_val = -EFAULT; | ||
2814 | break; | ||
2815 | } | ||
2816 | default: | 2793 | default: |
2817 | ret_val = -ENOIOCTLCMD; | 2794 | ret_val = -ENOIOCTLCMD; |
2818 | } | 2795 | } |
@@ -2823,6 +2800,31 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
2823 | return ret_val; | 2800 | return ret_val; |
2824 | } /* cy_ioctl */ | 2801 | } /* cy_ioctl */ |
2825 | 2802 | ||
2803 | static int cy_get_icount(struct tty_struct *tty, | ||
2804 | struct serial_icounter_struct *sic) | ||
2805 | { | ||
2806 | struct cyclades_port *info = tty->driver_data; | ||
2807 | struct cyclades_icount cnow; /* Used to snapshot */ | ||
2808 | unsigned long flags; | ||
2809 | |||
2810 | spin_lock_irqsave(&info->card->card_lock, flags); | ||
2811 | cnow = info->icount; | ||
2812 | spin_unlock_irqrestore(&info->card->card_lock, flags); | ||
2813 | |||
2814 | sic->cts = cnow.cts; | ||
2815 | sic->dsr = cnow.dsr; | ||
2816 | sic->rng = cnow.rng; | ||
2817 | sic->dcd = cnow.dcd; | ||
2818 | sic->rx = cnow.rx; | ||
2819 | sic->tx = cnow.tx; | ||
2820 | sic->frame = cnow.frame; | ||
2821 | sic->overrun = cnow.overrun; | ||
2822 | sic->parity = cnow.parity; | ||
2823 | sic->brk = cnow.brk; | ||
2824 | sic->buf_overrun = cnow.buf_overrun; | ||
2825 | return 0; | ||
2826 | } | ||
2827 | |||
2826 | /* | 2828 | /* |
2827 | * This routine allows the tty driver to be notified when | 2829 | * This routine allows the tty driver to be notified when |
2828 | * device's termios settings have changed. Note that a | 2830 | * device's termios settings have changed. Note that a |
@@ -4084,6 +4086,7 @@ static const struct tty_operations cy_ops = { | |||
4084 | .wait_until_sent = cy_wait_until_sent, | 4086 | .wait_until_sent = cy_wait_until_sent, |
4085 | .tiocmget = cy_tiocmget, | 4087 | .tiocmget = cy_tiocmget, |
4086 | .tiocmset = cy_tiocmset, | 4088 | .tiocmset = cy_tiocmset, |
4089 | .get_icount = cy_get_icount, | ||
4087 | .proc_fops = &cyclades_proc_fops, | 4090 | .proc_fops = &cyclades_proc_fops, |
4088 | }; | 4091 | }; |
4089 | 4092 | ||
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index d4b71e8d0d23..438272ca9e08 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -183,6 +183,8 @@ static void ip2_hangup(PTTY); | |||
183 | static int ip2_tiocmget(struct tty_struct *tty, struct file *file); | 183 | static int ip2_tiocmget(struct tty_struct *tty, struct file *file); |
184 | static int ip2_tiocmset(struct tty_struct *tty, struct file *file, | 184 | static int ip2_tiocmset(struct tty_struct *tty, struct file *file, |
185 | unsigned int set, unsigned int clear); | 185 | unsigned int set, unsigned int clear); |
186 | static int ip2_get_icount(struct tty_struct *tty, | ||
187 | struct serial_icounter_struct *icount); | ||
186 | 188 | ||
187 | static void set_irq(int, int); | 189 | static void set_irq(int, int); |
188 | static void ip2_interrupt_bh(struct work_struct *work); | 190 | static void ip2_interrupt_bh(struct work_struct *work); |
@@ -454,6 +456,7 @@ static const struct tty_operations ip2_ops = { | |||
454 | .hangup = ip2_hangup, | 456 | .hangup = ip2_hangup, |
455 | .tiocmget = ip2_tiocmget, | 457 | .tiocmget = ip2_tiocmget, |
456 | .tiocmset = ip2_tiocmset, | 458 | .tiocmset = ip2_tiocmset, |
459 | .get_icount = ip2_get_icount, | ||
457 | .proc_fops = &ip2_proc_fops, | 460 | .proc_fops = &ip2_proc_fops, |
458 | }; | 461 | }; |
459 | 462 | ||
@@ -2128,7 +2131,6 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) | |||
2128 | i2ChanStrPtr pCh = DevTable[tty->index]; | 2131 | i2ChanStrPtr pCh = DevTable[tty->index]; |
2129 | i2eBordStrPtr pB; | 2132 | i2eBordStrPtr pB; |
2130 | struct async_icount cprev, cnow; /* kernel counter temps */ | 2133 | struct async_icount cprev, cnow; /* kernel counter temps */ |
2131 | struct serial_icounter_struct __user *p_cuser; | ||
2132 | int rc = 0; | 2134 | int rc = 0; |
2133 | unsigned long flags; | 2135 | unsigned long flags; |
2134 | void __user *argp = (void __user *)arg; | 2136 | void __user *argp = (void __user *)arg; |
@@ -2297,34 +2299,6 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) | |||
2297 | break; | 2299 | break; |
2298 | 2300 | ||
2299 | /* | 2301 | /* |
2300 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
2301 | * Return: write counters to the user passed counter struct | ||
2302 | * NB: both 1->0 and 0->1 transitions are counted except for RI where | ||
2303 | * only 0->1 is counted. The controller is quite capable of counting | ||
2304 | * both, but this done to preserve compatibility with the standard | ||
2305 | * serial driver. | ||
2306 | */ | ||
2307 | case TIOCGICOUNT: | ||
2308 | ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc ); | ||
2309 | |||
2310 | write_lock_irqsave(&pB->read_fifo_spinlock, flags); | ||
2311 | cnow = pCh->icount; | ||
2312 | write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); | ||
2313 | p_cuser = argp; | ||
2314 | rc = put_user(cnow.cts, &p_cuser->cts); | ||
2315 | rc = put_user(cnow.dsr, &p_cuser->dsr); | ||
2316 | rc = put_user(cnow.rng, &p_cuser->rng); | ||
2317 | rc = put_user(cnow.dcd, &p_cuser->dcd); | ||
2318 | rc = put_user(cnow.rx, &p_cuser->rx); | ||
2319 | rc = put_user(cnow.tx, &p_cuser->tx); | ||
2320 | rc = put_user(cnow.frame, &p_cuser->frame); | ||
2321 | rc = put_user(cnow.overrun, &p_cuser->overrun); | ||
2322 | rc = put_user(cnow.parity, &p_cuser->parity); | ||
2323 | rc = put_user(cnow.brk, &p_cuser->brk); | ||
2324 | rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun); | ||
2325 | break; | ||
2326 | |||
2327 | /* | ||
2328 | * The rest are not supported by this driver. By returning -ENOIOCTLCMD they | 2302 | * The rest are not supported by this driver. By returning -ENOIOCTLCMD they |
2329 | * will be passed to the line discipline for it to handle. | 2303 | * will be passed to the line discipline for it to handle. |
2330 | */ | 2304 | */ |
@@ -2348,6 +2322,46 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) | |||
2348 | return rc; | 2322 | return rc; |
2349 | } | 2323 | } |
2350 | 2324 | ||
2325 | static int ip2_get_icount(struct tty_struct *tty, | ||
2326 | struct serial_icounter_struct *icount) | ||
2327 | { | ||
2328 | i2ChanStrPtr pCh = DevTable[tty->index]; | ||
2329 | i2eBordStrPtr pB; | ||
2330 | struct async_icount cnow; /* kernel counter temp */ | ||
2331 | unsigned long flags; | ||
2332 | |||
2333 | if ( pCh == NULL ) | ||
2334 | return -ENODEV; | ||
2335 | |||
2336 | pB = pCh->pMyBord; | ||
2337 | |||
2338 | /* | ||
2339 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
2340 | * Return: write counters to the user passed counter struct | ||
2341 | * NB: both 1->0 and 0->1 transitions are counted except for RI where | ||
2342 | * only 0->1 is counted. The controller is quite capable of counting | ||
2343 | * both, but this done to preserve compatibility with the standard | ||
2344 | * serial driver. | ||
2345 | */ | ||
2346 | |||
2347 | write_lock_irqsave(&pB->read_fifo_spinlock, flags); | ||
2348 | cnow = pCh->icount; | ||
2349 | write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); | ||
2350 | |||
2351 | icount->cts = cnow.cts; | ||
2352 | icount->dsr = cnow.dsr; | ||
2353 | icount->rng = cnow.rng; | ||
2354 | icount->dcd = cnow.dcd; | ||
2355 | icount->rx = cnow.rx; | ||
2356 | icount->tx = cnow.tx; | ||
2357 | icount->frame = cnow.frame; | ||
2358 | icount->overrun = cnow.overrun; | ||
2359 | icount->parity = cnow.parity; | ||
2360 | icount->brk = cnow.brk; | ||
2361 | icount->buf_overrun = cnow.buf_overrun; | ||
2362 | return 0; | ||
2363 | } | ||
2364 | |||
2351 | /******************************************************************************/ | 2365 | /******************************************************************************/ |
2352 | /* Function: GetSerialInfo() */ | 2366 | /* Function: GetSerialInfo() */ |
2353 | /* Parameters: Pointer to channel structure */ | 2367 | /* Parameters: Pointer to channel structure */ |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 9d243de795df..463df27494bd 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -1700,7 +1700,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1700 | return 0; | 1700 | return 0; |
1701 | } | 1701 | } |
1702 | 1702 | ||
1703 | if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && cmd != TIOCGICOUNT && | 1703 | if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && |
1704 | test_bit(TTY_IO_ERROR, &tty->flags)) | 1704 | test_bit(TTY_IO_ERROR, &tty->flags)) |
1705 | return -EIO; | 1705 | return -EIO; |
1706 | 1706 | ||
@@ -1730,32 +1730,6 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1730 | 1730 | ||
1731 | return wait_event_interruptible(info->port.delta_msr_wait, | 1731 | return wait_event_interruptible(info->port.delta_msr_wait, |
1732 | mxser_cflags_changed(info, arg, &cnow)); | 1732 | mxser_cflags_changed(info, arg, &cnow)); |
1733 | /* | ||
1734 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
1735 | * Return: write counters to the user passed counter struct | ||
1736 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
1737 | * RI where only 0->1 is counted. | ||
1738 | */ | ||
1739 | case TIOCGICOUNT: { | ||
1740 | struct serial_icounter_struct icnt = { 0 }; | ||
1741 | spin_lock_irqsave(&info->slock, flags); | ||
1742 | cnow = info->icount; | ||
1743 | spin_unlock_irqrestore(&info->slock, flags); | ||
1744 | |||
1745 | icnt.frame = cnow.frame; | ||
1746 | icnt.brk = cnow.brk; | ||
1747 | icnt.overrun = cnow.overrun; | ||
1748 | icnt.buf_overrun = cnow.buf_overrun; | ||
1749 | icnt.parity = cnow.parity; | ||
1750 | icnt.rx = cnow.rx; | ||
1751 | icnt.tx = cnow.tx; | ||
1752 | icnt.cts = cnow.cts; | ||
1753 | icnt.dsr = cnow.dsr; | ||
1754 | icnt.rng = cnow.rng; | ||
1755 | icnt.dcd = cnow.dcd; | ||
1756 | |||
1757 | return copy_to_user(argp, &icnt, sizeof(icnt)) ? -EFAULT : 0; | ||
1758 | } | ||
1759 | case MOXA_HighSpeedOn: | 1733 | case MOXA_HighSpeedOn: |
1760 | return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); | 1734 | return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); |
1761 | case MOXA_SDS_RSTICOUNTER: | 1735 | case MOXA_SDS_RSTICOUNTER: |
@@ -1828,6 +1802,39 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1828 | return 0; | 1802 | return 0; |
1829 | } | 1803 | } |
1830 | 1804 | ||
1805 | /* | ||
1806 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
1807 | * Return: write counters to the user passed counter struct | ||
1808 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
1809 | * RI where only 0->1 is counted. | ||
1810 | */ | ||
1811 | |||
1812 | static int mxser_get_icount(struct tty_struct *tty, | ||
1813 | struct serial_icounter_struct *icount) | ||
1814 | |||
1815 | { | ||
1816 | struct mxser_port *info = tty->driver_data; | ||
1817 | struct async_icount cnow; | ||
1818 | unsigned long flags; | ||
1819 | |||
1820 | spin_lock_irqsave(&info->slock, flags); | ||
1821 | cnow = info->icount; | ||
1822 | spin_unlock_irqrestore(&info->slock, flags); | ||
1823 | |||
1824 | icount->frame = cnow.frame; | ||
1825 | icount->brk = cnow.brk; | ||
1826 | icount->overrun = cnow.overrun; | ||
1827 | icount->buf_overrun = cnow.buf_overrun; | ||
1828 | icount->parity = cnow.parity; | ||
1829 | icount->rx = cnow.rx; | ||
1830 | icount->tx = cnow.tx; | ||
1831 | icount->cts = cnow.cts; | ||
1832 | icount->dsr = cnow.dsr; | ||
1833 | icount->rng = cnow.rng; | ||
1834 | icount->dcd = cnow.dcd; | ||
1835 | return 0; | ||
1836 | } | ||
1837 | |||
1831 | static void mxser_stoprx(struct tty_struct *tty) | 1838 | static void mxser_stoprx(struct tty_struct *tty) |
1832 | { | 1839 | { |
1833 | struct mxser_port *info = tty->driver_data; | 1840 | struct mxser_port *info = tty->driver_data; |
@@ -2326,6 +2333,7 @@ static const struct tty_operations mxser_ops = { | |||
2326 | .wait_until_sent = mxser_wait_until_sent, | 2333 | .wait_until_sent = mxser_wait_until_sent, |
2327 | .tiocmget = mxser_tiocmget, | 2334 | .tiocmget = mxser_tiocmget, |
2328 | .tiocmset = mxser_tiocmset, | 2335 | .tiocmset = mxser_tiocmset, |
2336 | .get_icount = mxser_get_icount, | ||
2329 | }; | 2337 | }; |
2330 | 2338 | ||
2331 | struct tty_port_operations mxser_port_ops = { | 2339 | struct tty_port_operations mxser_port_ops = { |
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 817169cbb245..dd3f9b1f11b4 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c | |||
@@ -1804,24 +1804,24 @@ static int ntty_cflags_changed(struct port *port, unsigned long flags, | |||
1804 | return ret; | 1804 | return ret; |
1805 | } | 1805 | } |
1806 | 1806 | ||
1807 | static int ntty_ioctl_tiocgicount(struct port *port, void __user *argp) | 1807 | static int ntty_tiocgicount(struct tty_struct *tty, |
1808 | struct serial_icounter_struct *icount) | ||
1808 | { | 1809 | { |
1810 | struct port *port = tty->driver_data; | ||
1809 | const struct async_icount cnow = port->tty_icount; | 1811 | const struct async_icount cnow = port->tty_icount; |
1810 | struct serial_icounter_struct icount; | 1812 | |
1811 | 1813 | icount->cts = cnow.cts; | |
1812 | icount.cts = cnow.cts; | 1814 | icount->dsr = cnow.dsr; |
1813 | icount.dsr = cnow.dsr; | 1815 | icount->rng = cnow.rng; |
1814 | icount.rng = cnow.rng; | 1816 | icount->dcd = cnow.dcd; |
1815 | icount.dcd = cnow.dcd; | 1817 | icount->rx = cnow.rx; |
1816 | icount.rx = cnow.rx; | 1818 | icount->tx = cnow.tx; |
1817 | icount.tx = cnow.tx; | 1819 | icount->frame = cnow.frame; |
1818 | icount.frame = cnow.frame; | 1820 | icount->overrun = cnow.overrun; |
1819 | icount.overrun = cnow.overrun; | 1821 | icount->parity = cnow.parity; |
1820 | icount.parity = cnow.parity; | 1822 | icount->brk = cnow.brk; |
1821 | icount.brk = cnow.brk; | 1823 | icount->buf_overrun = cnow.buf_overrun; |
1822 | icount.buf_overrun = cnow.buf_overrun; | 1824 | return 0; |
1823 | |||
1824 | return copy_to_user(argp, &icount, sizeof(icount)) ? -EFAULT : 0; | ||
1825 | } | 1825 | } |
1826 | 1826 | ||
1827 | static int ntty_ioctl(struct tty_struct *tty, struct file *file, | 1827 | static int ntty_ioctl(struct tty_struct *tty, struct file *file, |
@@ -1840,9 +1840,7 @@ static int ntty_ioctl(struct tty_struct *tty, struct file *file, | |||
1840 | rval = wait_event_interruptible(port->tty_wait, | 1840 | rval = wait_event_interruptible(port->tty_wait, |
1841 | ntty_cflags_changed(port, arg, &cprev)); | 1841 | ntty_cflags_changed(port, arg, &cprev)); |
1842 | break; | 1842 | break; |
1843 | } case TIOCGICOUNT: | 1843 | } |
1844 | rval = ntty_ioctl_tiocgicount(port, argp); | ||
1845 | break; | ||
1846 | default: | 1844 | default: |
1847 | DBG1("ERR: 0x%08X, %d", cmd, cmd); | 1845 | DBG1("ERR: 0x%08X, %d", cmd, cmd); |
1848 | break; | 1846 | break; |
@@ -1922,6 +1920,7 @@ static const struct tty_operations tty_ops = { | |||
1922 | .chars_in_buffer = ntty_chars_in_buffer, | 1920 | .chars_in_buffer = ntty_chars_in_buffer, |
1923 | .tiocmget = ntty_tiocmget, | 1921 | .tiocmget = ntty_tiocmget, |
1924 | .tiocmset = ntty_tiocmset, | 1922 | .tiocmset = ntty_tiocmset, |
1923 | .get_icount = ntty_tiocgicount, | ||
1925 | .install = ntty_install, | 1924 | .install = ntty_install, |
1926 | .cleanup = ntty_cleanup, | 1925 | .cleanup = ntty_cleanup, |
1927 | }; | 1926 | }; |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 9ecd6bef5d3b..8e7c78131e32 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -2215,6 +2215,32 @@ static int mgslpc_break(struct tty_struct *tty, int break_state) | |||
2215 | return 0; | 2215 | return 0; |
2216 | } | 2216 | } |
2217 | 2217 | ||
2218 | static int mgslpc_get_icount(struct tty_struct *tty, | ||
2219 | struct serial_icounter_struct *icount) | ||
2220 | { | ||
2221 | MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data; | ||
2222 | struct mgsl_icount cnow; /* kernel counter temps */ | ||
2223 | unsigned long flags; | ||
2224 | |||
2225 | spin_lock_irqsave(&info->lock,flags); | ||
2226 | cnow = info->icount; | ||
2227 | spin_unlock_irqrestore(&info->lock,flags); | ||
2228 | |||
2229 | icount->cts = cnow.cts; | ||
2230 | icount->dsr = cnow.dsr; | ||
2231 | icount->rng = cnow.rng; | ||
2232 | icount->dcd = cnow.dcd; | ||
2233 | icount->rx = cnow.rx; | ||
2234 | icount->tx = cnow.tx; | ||
2235 | icount->frame = cnow.frame; | ||
2236 | icount->overrun = cnow.overrun; | ||
2237 | icount->parity = cnow.parity; | ||
2238 | icount->brk = cnow.brk; | ||
2239 | icount->buf_overrun = cnow.buf_overrun; | ||
2240 | |||
2241 | return 0; | ||
2242 | } | ||
2243 | |||
2218 | /* Service an IOCTL request | 2244 | /* Service an IOCTL request |
2219 | * | 2245 | * |
2220 | * Arguments: | 2246 | * Arguments: |
@@ -2230,11 +2256,7 @@ static int mgslpc_ioctl(struct tty_struct *tty, struct file * file, | |||
2230 | unsigned int cmd, unsigned long arg) | 2256 | unsigned int cmd, unsigned long arg) |
2231 | { | 2257 | { |
2232 | MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data; | 2258 | MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data; |
2233 | int error; | ||
2234 | struct mgsl_icount cnow; /* kernel counter temps */ | ||
2235 | struct serial_icounter_struct __user *p_cuser; /* user space */ | ||
2236 | void __user *argp = (void __user *)arg; | 2259 | void __user *argp = (void __user *)arg; |
2237 | unsigned long flags; | ||
2238 | 2260 | ||
2239 | if (debug_level >= DEBUG_LEVEL_INFO) | 2261 | if (debug_level >= DEBUG_LEVEL_INFO) |
2240 | printk("%s(%d):mgslpc_ioctl %s cmd=%08X\n", __FILE__,__LINE__, | 2262 | printk("%s(%d):mgslpc_ioctl %s cmd=%08X\n", __FILE__,__LINE__, |
@@ -2244,7 +2266,7 @@ static int mgslpc_ioctl(struct tty_struct *tty, struct file * file, | |||
2244 | return -ENODEV; | 2266 | return -ENODEV; |
2245 | 2267 | ||
2246 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 2268 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
2247 | (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { | 2269 | (cmd != TIOCMIWAIT)) { |
2248 | if (tty->flags & (1 << TTY_IO_ERROR)) | 2270 | if (tty->flags & (1 << TTY_IO_ERROR)) |
2249 | return -EIO; | 2271 | return -EIO; |
2250 | } | 2272 | } |
@@ -2274,34 +2296,6 @@ static int mgslpc_ioctl(struct tty_struct *tty, struct file * file, | |||
2274 | return wait_events(info, argp); | 2296 | return wait_events(info, argp); |
2275 | case TIOCMIWAIT: | 2297 | case TIOCMIWAIT: |
2276 | return modem_input_wait(info,(int)arg); | 2298 | return modem_input_wait(info,(int)arg); |
2277 | case TIOCGICOUNT: | ||
2278 | spin_lock_irqsave(&info->lock,flags); | ||
2279 | cnow = info->icount; | ||
2280 | spin_unlock_irqrestore(&info->lock,flags); | ||
2281 | p_cuser = argp; | ||
2282 | PUT_USER(error,cnow.cts, &p_cuser->cts); | ||
2283 | if (error) return error; | ||
2284 | PUT_USER(error,cnow.dsr, &p_cuser->dsr); | ||
2285 | if (error) return error; | ||
2286 | PUT_USER(error,cnow.rng, &p_cuser->rng); | ||
2287 | if (error) return error; | ||
2288 | PUT_USER(error,cnow.dcd, &p_cuser->dcd); | ||
2289 | if (error) return error; | ||
2290 | PUT_USER(error,cnow.rx, &p_cuser->rx); | ||
2291 | if (error) return error; | ||
2292 | PUT_USER(error,cnow.tx, &p_cuser->tx); | ||
2293 | if (error) return error; | ||
2294 | PUT_USER(error,cnow.frame, &p_cuser->frame); | ||
2295 | if (error) return error; | ||
2296 | PUT_USER(error,cnow.overrun, &p_cuser->overrun); | ||
2297 | if (error) return error; | ||
2298 | PUT_USER(error,cnow.parity, &p_cuser->parity); | ||
2299 | if (error) return error; | ||
2300 | PUT_USER(error,cnow.brk, &p_cuser->brk); | ||
2301 | if (error) return error; | ||
2302 | PUT_USER(error,cnow.buf_overrun, &p_cuser->buf_overrun); | ||
2303 | if (error) return error; | ||
2304 | return 0; | ||
2305 | default: | 2299 | default: |
2306 | return -ENOIOCTLCMD; | 2300 | return -ENOIOCTLCMD; |
2307 | } | 2301 | } |
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 | ||
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index e63b830c86cc..1746d91205f7 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -1032,9 +1032,6 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1032 | unsigned int cmd, unsigned long arg) | 1032 | unsigned int cmd, unsigned long arg) |
1033 | { | 1033 | { |
1034 | struct slgt_info *info = tty->driver_data; | 1034 | struct slgt_info *info = tty->driver_data; |
1035 | struct mgsl_icount cnow; /* kernel counter temps */ | ||
1036 | struct serial_icounter_struct __user *p_cuser; /* user space */ | ||
1037 | unsigned long flags; | ||
1038 | void __user *argp = (void __user *)arg; | 1035 | void __user *argp = (void __user *)arg; |
1039 | int ret; | 1036 | int ret; |
1040 | 1037 | ||
@@ -1043,7 +1040,7 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1043 | DBGINFO(("%s ioctl() cmd=%08X\n", info->device_name, cmd)); | 1040 | DBGINFO(("%s ioctl() cmd=%08X\n", info->device_name, cmd)); |
1044 | 1041 | ||
1045 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 1042 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
1046 | (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { | 1043 | (cmd != TIOCMIWAIT)) { |
1047 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1044 | if (tty->flags & (1 << TTY_IO_ERROR)) |
1048 | return -EIO; | 1045 | return -EIO; |
1049 | } | 1046 | } |
@@ -1053,24 +1050,6 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1053 | return wait_mgsl_event(info, argp); | 1050 | return wait_mgsl_event(info, argp); |
1054 | case TIOCMIWAIT: | 1051 | case TIOCMIWAIT: |
1055 | return modem_input_wait(info,(int)arg); | 1052 | return modem_input_wait(info,(int)arg); |
1056 | case TIOCGICOUNT: | ||
1057 | spin_lock_irqsave(&info->lock,flags); | ||
1058 | cnow = info->icount; | ||
1059 | spin_unlock_irqrestore(&info->lock,flags); | ||
1060 | p_cuser = argp; | ||
1061 | if (put_user(cnow.cts, &p_cuser->cts) || | ||
1062 | put_user(cnow.dsr, &p_cuser->dsr) || | ||
1063 | put_user(cnow.rng, &p_cuser->rng) || | ||
1064 | put_user(cnow.dcd, &p_cuser->dcd) || | ||
1065 | put_user(cnow.rx, &p_cuser->rx) || | ||
1066 | put_user(cnow.tx, &p_cuser->tx) || | ||
1067 | put_user(cnow.frame, &p_cuser->frame) || | ||
1068 | put_user(cnow.overrun, &p_cuser->overrun) || | ||
1069 | put_user(cnow.parity, &p_cuser->parity) || | ||
1070 | put_user(cnow.brk, &p_cuser->brk) || | ||
1071 | put_user(cnow.buf_overrun, &p_cuser->buf_overrun)) | ||
1072 | return -EFAULT; | ||
1073 | return 0; | ||
1074 | case MGSL_IOCSGPIO: | 1053 | case MGSL_IOCSGPIO: |
1075 | return set_gpio(info, argp); | 1054 | return set_gpio(info, argp); |
1076 | case MGSL_IOCGGPIO: | 1055 | case MGSL_IOCGGPIO: |
@@ -1117,6 +1096,33 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1117 | return ret; | 1096 | return ret; |
1118 | } | 1097 | } |
1119 | 1098 | ||
1099 | static int get_icount(struct tty_struct *tty, | ||
1100 | struct serial_icounter_struct *icount) | ||
1101 | |||
1102 | { | ||
1103 | struct slgt_info *info = tty->driver_data; | ||
1104 | struct mgsl_icount cnow; /* kernel counter temps */ | ||
1105 | unsigned long flags; | ||
1106 | |||
1107 | spin_lock_irqsave(&info->lock,flags); | ||
1108 | cnow = info->icount; | ||
1109 | spin_unlock_irqrestore(&info->lock,flags); | ||
1110 | |||
1111 | icount->cts = cnow.cts; | ||
1112 | icount->dsr = cnow.dsr; | ||
1113 | icount->rng = cnow.rng; | ||
1114 | icount->dcd = cnow.dcd; | ||
1115 | icount->rx = cnow.rx; | ||
1116 | icount->tx = cnow.tx; | ||
1117 | icount->frame = cnow.frame; | ||
1118 | icount->overrun = cnow.overrun; | ||
1119 | icount->parity = cnow.parity; | ||
1120 | icount->brk = cnow.brk; | ||
1121 | icount->buf_overrun = cnow.buf_overrun; | ||
1122 | |||
1123 | return 0; | ||
1124 | } | ||
1125 | |||
1120 | /* | 1126 | /* |
1121 | * support for 32 bit ioctl calls on 64 bit systems | 1127 | * support for 32 bit ioctl calls on 64 bit systems |
1122 | */ | 1128 | */ |
@@ -1206,10 +1212,6 @@ static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file, | |||
1206 | case MGSL_IOCSGPIO: | 1212 | case MGSL_IOCSGPIO: |
1207 | case MGSL_IOCGGPIO: | 1213 | case MGSL_IOCGGPIO: |
1208 | case MGSL_IOCWAITGPIO: | 1214 | case MGSL_IOCWAITGPIO: |
1209 | case TIOCGICOUNT: | ||
1210 | rc = ioctl(tty, file, cmd, (unsigned long)(compat_ptr(arg))); | ||
1211 | break; | ||
1212 | |||
1213 | case MGSL_IOCSTXIDLE: | 1215 | case MGSL_IOCSTXIDLE: |
1214 | case MGSL_IOCTXENABLE: | 1216 | case MGSL_IOCTXENABLE: |
1215 | case MGSL_IOCRXENABLE: | 1217 | case MGSL_IOCRXENABLE: |
@@ -3642,6 +3644,7 @@ static const struct tty_operations ops = { | |||
3642 | .hangup = hangup, | 3644 | .hangup = hangup, |
3643 | .tiocmget = tiocmget, | 3645 | .tiocmget = tiocmget, |
3644 | .tiocmset = tiocmset, | 3646 | .tiocmset = tiocmset, |
3647 | .get_icount = get_icount, | ||
3645 | .proc_fops = &synclink_gt_proc_fops, | 3648 | .proc_fops = &synclink_gt_proc_fops, |
3646 | }; | 3649 | }; |
3647 | 3650 | ||
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index e56caf7d82aa..2f9eb4b0dec1 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -1258,10 +1258,6 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1258 | unsigned int cmd, unsigned long arg) | 1258 | unsigned int cmd, unsigned long arg) |
1259 | { | 1259 | { |
1260 | SLMP_INFO *info = tty->driver_data; | 1260 | SLMP_INFO *info = tty->driver_data; |
1261 | int error; | ||
1262 | struct mgsl_icount cnow; /* kernel counter temps */ | ||
1263 | struct serial_icounter_struct __user *p_cuser; /* user space */ | ||
1264 | unsigned long flags; | ||
1265 | void __user *argp = (void __user *)arg; | 1261 | void __user *argp = (void __user *)arg; |
1266 | 1262 | ||
1267 | if (debug_level >= DEBUG_LEVEL_INFO) | 1263 | if (debug_level >= DEBUG_LEVEL_INFO) |
@@ -1272,7 +1268,7 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1272 | return -ENODEV; | 1268 | return -ENODEV; |
1273 | 1269 | ||
1274 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 1270 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
1275 | (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { | 1271 | (cmd != TIOCMIWAIT)) { |
1276 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1272 | if (tty->flags & (1 << TTY_IO_ERROR)) |
1277 | return -EIO; | 1273 | return -EIO; |
1278 | } | 1274 | } |
@@ -1310,40 +1306,38 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1310 | * NB: both 1->0 and 0->1 transitions are counted except for | 1306 | * NB: both 1->0 and 0->1 transitions are counted except for |
1311 | * RI where only 0->1 is counted. | 1307 | * RI where only 0->1 is counted. |
1312 | */ | 1308 | */ |
1313 | case TIOCGICOUNT: | ||
1314 | spin_lock_irqsave(&info->lock,flags); | ||
1315 | cnow = info->icount; | ||
1316 | spin_unlock_irqrestore(&info->lock,flags); | ||
1317 | p_cuser = argp; | ||
1318 | PUT_USER(error,cnow.cts, &p_cuser->cts); | ||
1319 | if (error) return error; | ||
1320 | PUT_USER(error,cnow.dsr, &p_cuser->dsr); | ||
1321 | if (error) return error; | ||
1322 | PUT_USER(error,cnow.rng, &p_cuser->rng); | ||
1323 | if (error) return error; | ||
1324 | PUT_USER(error,cnow.dcd, &p_cuser->dcd); | ||
1325 | if (error) return error; | ||
1326 | PUT_USER(error,cnow.rx, &p_cuser->rx); | ||
1327 | if (error) return error; | ||
1328 | PUT_USER(error,cnow.tx, &p_cuser->tx); | ||
1329 | if (error) return error; | ||
1330 | PUT_USER(error,cnow.frame, &p_cuser->frame); | ||
1331 | if (error) return error; | ||
1332 | PUT_USER(error,cnow.overrun, &p_cuser->overrun); | ||
1333 | if (error) return error; | ||
1334 | PUT_USER(error,cnow.parity, &p_cuser->parity); | ||
1335 | if (error) return error; | ||
1336 | PUT_USER(error,cnow.brk, &p_cuser->brk); | ||
1337 | if (error) return error; | ||
1338 | PUT_USER(error,cnow.buf_overrun, &p_cuser->buf_overrun); | ||
1339 | if (error) return error; | ||
1340 | return 0; | ||
1341 | default: | 1309 | default: |
1342 | return -ENOIOCTLCMD; | 1310 | return -ENOIOCTLCMD; |
1343 | } | 1311 | } |
1344 | return 0; | 1312 | return 0; |
1345 | } | 1313 | } |
1346 | 1314 | ||
1315 | static int get_icount(struct tty_struct *tty, | ||
1316 | struct serial_icounter_struct *icount) | ||
1317 | { | ||
1318 | SLMP_INFO *info = tty->driver_data; | ||
1319 | struct mgsl_icount cnow; /* kernel counter temps */ | ||
1320 | unsigned long flags; | ||
1321 | |||
1322 | spin_lock_irqsave(&info->lock,flags); | ||
1323 | cnow = info->icount; | ||
1324 | spin_unlock_irqrestore(&info->lock,flags); | ||
1325 | |||
1326 | icount->cts = cnow.cts; | ||
1327 | icount->dsr = cnow.dsr; | ||
1328 | icount->rng = cnow.rng; | ||
1329 | icount->dcd = cnow.dcd; | ||
1330 | icount->rx = cnow.rx; | ||
1331 | icount->tx = cnow.tx; | ||
1332 | icount->frame = cnow.frame; | ||
1333 | icount->overrun = cnow.overrun; | ||
1334 | icount->parity = cnow.parity; | ||
1335 | icount->brk = cnow.brk; | ||
1336 | icount->buf_overrun = cnow.buf_overrun; | ||
1337 | |||
1338 | return 0; | ||
1339 | } | ||
1340 | |||
1347 | /* | 1341 | /* |
1348 | * /proc fs routines.... | 1342 | * /proc fs routines.... |
1349 | */ | 1343 | */ |
@@ -3909,6 +3903,7 @@ static const struct tty_operations ops = { | |||
3909 | .hangup = hangup, | 3903 | .hangup = hangup, |
3910 | .tiocmget = tiocmget, | 3904 | .tiocmget = tiocmget, |
3911 | .tiocmset = tiocmset, | 3905 | .tiocmset = tiocmset, |
3906 | .get_icount = get_icount, | ||
3912 | .proc_fops = &synclinkmp_proc_fops, | 3907 | .proc_fops = &synclinkmp_proc_fops, |
3913 | }; | 3908 | }; |
3914 | 3909 | ||
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c index 0dff3bbddc8b..88b13356ec10 100644 --- a/drivers/serial/68360serial.c +++ b/drivers/serial/68360serial.c | |||
@@ -1381,6 +1381,30 @@ static void send_break(ser_info_t *info, unsigned int duration) | |||
1381 | } | 1381 | } |
1382 | 1382 | ||
1383 | 1383 | ||
1384 | /* | ||
1385 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
1386 | * Return: write counters to the user passed counter struct | ||
1387 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
1388 | * RI where only 0->1 is counted. | ||
1389 | */ | ||
1390 | static int rs_360_get_icount(struct tty_struct *tty, | ||
1391 | struct serial_icounter_struct *icount) | ||
1392 | { | ||
1393 | ser_info_t *info = (ser_info_t *)tty->driver_data; | ||
1394 | struct async_icount cnow; | ||
1395 | |||
1396 | local_irq_disable(); | ||
1397 | cnow = info->state->icount; | ||
1398 | local_irq_enable(); | ||
1399 | |||
1400 | icount->cts = cnow.cts; | ||
1401 | icount->dsr = cnow.dsr; | ||
1402 | icount->rng = cnow.rng; | ||
1403 | icount->dcd = cnow.dcd; | ||
1404 | |||
1405 | return 0; | ||
1406 | } | ||
1407 | |||
1384 | static int rs_360_ioctl(struct tty_struct *tty, struct file * file, | 1408 | static int rs_360_ioctl(struct tty_struct *tty, struct file * file, |
1385 | unsigned int cmd, unsigned long arg) | 1409 | unsigned int cmd, unsigned long arg) |
1386 | { | 1410 | { |
@@ -1394,7 +1418,7 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file, | |||
1394 | if (serial_paranoia_check(info, tty->name, "rs_ioctl")) | 1418 | if (serial_paranoia_check(info, tty->name, "rs_ioctl")) |
1395 | return -ENODEV; | 1419 | return -ENODEV; |
1396 | 1420 | ||
1397 | if ((cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { | 1421 | if (cmd != TIOCMIWAIT) { |
1398 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1422 | if (tty->flags & (1 << TTY_IO_ERROR)) |
1399 | return -EIO; | 1423 | return -EIO; |
1400 | } | 1424 | } |
@@ -1477,31 +1501,6 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file, | |||
1477 | return 0; | 1501 | return 0; |
1478 | #endif | 1502 | #endif |
1479 | 1503 | ||
1480 | /* | ||
1481 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
1482 | * Return: write counters to the user passed counter struct | ||
1483 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
1484 | * RI where only 0->1 is counted. | ||
1485 | */ | ||
1486 | case TIOCGICOUNT: | ||
1487 | local_irq_disable(); | ||
1488 | cnow = info->state->icount; | ||
1489 | local_irq_enable(); | ||
1490 | p_cuser = (struct serial_icounter_struct *) arg; | ||
1491 | /* error = put_user(cnow.cts, &p_cuser->cts); */ | ||
1492 | /* if (error) return error; */ | ||
1493 | /* error = put_user(cnow.dsr, &p_cuser->dsr); */ | ||
1494 | /* if (error) return error; */ | ||
1495 | /* error = put_user(cnow.rng, &p_cuser->rng); */ | ||
1496 | /* if (error) return error; */ | ||
1497 | /* error = put_user(cnow.dcd, &p_cuser->dcd); */ | ||
1498 | /* if (error) return error; */ | ||
1499 | |||
1500 | put_user(cnow.cts, &p_cuser->cts); | ||
1501 | put_user(cnow.dsr, &p_cuser->dsr); | ||
1502 | put_user(cnow.rng, &p_cuser->rng); | ||
1503 | put_user(cnow.dcd, &p_cuser->dcd); | ||
1504 | return 0; | ||
1505 | 1504 | ||
1506 | default: | 1505 | default: |
1507 | return -ENOIOCTLCMD; | 1506 | return -ENOIOCTLCMD; |