diff options
Diffstat (limited to 'drivers/char/ip2/ip2main.c')
-rw-r--r-- | drivers/char/ip2/ip2main.c | 72 |
1 files changed, 43 insertions, 29 deletions
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 64a439ce2f89..fcd02baa7d65 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -184,6 +184,8 @@ static void ip2_hangup(PTTY); | |||
184 | static int ip2_tiocmget(struct tty_struct *tty, struct file *file); | 184 | static int ip2_tiocmget(struct tty_struct *tty, struct file *file); |
185 | static int ip2_tiocmset(struct tty_struct *tty, struct file *file, | 185 | static int ip2_tiocmset(struct tty_struct *tty, struct file *file, |
186 | unsigned int set, unsigned int clear); | 186 | unsigned int set, unsigned int clear); |
187 | static int ip2_get_icount(struct tty_struct *tty, | ||
188 | struct serial_icounter_struct *icount); | ||
187 | 189 | ||
188 | static void set_irq(int, int); | 190 | static void set_irq(int, int); |
189 | static void ip2_interrupt_bh(struct work_struct *work); | 191 | static void ip2_interrupt_bh(struct work_struct *work); |
@@ -456,6 +458,7 @@ static const struct tty_operations ip2_ops = { | |||
456 | .hangup = ip2_hangup, | 458 | .hangup = ip2_hangup, |
457 | .tiocmget = ip2_tiocmget, | 459 | .tiocmget = ip2_tiocmget, |
458 | .tiocmset = ip2_tiocmset, | 460 | .tiocmset = ip2_tiocmset, |
461 | .get_icount = ip2_get_icount, | ||
459 | .proc_fops = &ip2_proc_fops, | 462 | .proc_fops = &ip2_proc_fops, |
460 | }; | 463 | }; |
461 | 464 | ||
@@ -2130,7 +2133,6 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) | |||
2130 | i2ChanStrPtr pCh = DevTable[tty->index]; | 2133 | i2ChanStrPtr pCh = DevTable[tty->index]; |
2131 | i2eBordStrPtr pB; | 2134 | i2eBordStrPtr pB; |
2132 | struct async_icount cprev, cnow; /* kernel counter temps */ | 2135 | struct async_icount cprev, cnow; /* kernel counter temps */ |
2133 | struct serial_icounter_struct __user *p_cuser; | ||
2134 | int rc = 0; | 2136 | int rc = 0; |
2135 | unsigned long flags; | 2137 | unsigned long flags; |
2136 | void __user *argp = (void __user *)arg; | 2138 | void __user *argp = (void __user *)arg; |
@@ -2299,34 +2301,6 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) | |||
2299 | break; | 2301 | break; |
2300 | 2302 | ||
2301 | /* | 2303 | /* |
2302 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
2303 | * Return: write counters to the user passed counter struct | ||
2304 | * NB: both 1->0 and 0->1 transitions are counted except for RI where | ||
2305 | * only 0->1 is counted. The controller is quite capable of counting | ||
2306 | * both, but this done to preserve compatibility with the standard | ||
2307 | * serial driver. | ||
2308 | */ | ||
2309 | case TIOCGICOUNT: | ||
2310 | ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc ); | ||
2311 | |||
2312 | write_lock_irqsave(&pB->read_fifo_spinlock, flags); | ||
2313 | cnow = pCh->icount; | ||
2314 | write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); | ||
2315 | p_cuser = argp; | ||
2316 | rc = put_user(cnow.cts, &p_cuser->cts); | ||
2317 | rc = put_user(cnow.dsr, &p_cuser->dsr); | ||
2318 | rc = put_user(cnow.rng, &p_cuser->rng); | ||
2319 | rc = put_user(cnow.dcd, &p_cuser->dcd); | ||
2320 | rc = put_user(cnow.rx, &p_cuser->rx); | ||
2321 | rc = put_user(cnow.tx, &p_cuser->tx); | ||
2322 | rc = put_user(cnow.frame, &p_cuser->frame); | ||
2323 | rc = put_user(cnow.overrun, &p_cuser->overrun); | ||
2324 | rc = put_user(cnow.parity, &p_cuser->parity); | ||
2325 | rc = put_user(cnow.brk, &p_cuser->brk); | ||
2326 | rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun); | ||
2327 | break; | ||
2328 | |||
2329 | /* | ||
2330 | * The rest are not supported by this driver. By returning -ENOIOCTLCMD they | 2304 | * The rest are not supported by this driver. By returning -ENOIOCTLCMD they |
2331 | * will be passed to the line discipline for it to handle. | 2305 | * will be passed to the line discipline for it to handle. |
2332 | */ | 2306 | */ |
@@ -2350,6 +2324,46 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) | |||
2350 | return rc; | 2324 | return rc; |
2351 | } | 2325 | } |
2352 | 2326 | ||
2327 | static int ip2_get_icount(struct tty_struct *tty, | ||
2328 | struct serial_icounter_struct *icount) | ||
2329 | { | ||
2330 | i2ChanStrPtr pCh = DevTable[tty->index]; | ||
2331 | i2eBordStrPtr pB; | ||
2332 | struct async_icount cnow; /* kernel counter temp */ | ||
2333 | unsigned long flags; | ||
2334 | |||
2335 | if ( pCh == NULL ) | ||
2336 | return -ENODEV; | ||
2337 | |||
2338 | pB = pCh->pMyBord; | ||
2339 | |||
2340 | /* | ||
2341 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
2342 | * Return: write counters to the user passed counter struct | ||
2343 | * NB: both 1->0 and 0->1 transitions are counted except for RI where | ||
2344 | * only 0->1 is counted. The controller is quite capable of counting | ||
2345 | * both, but this done to preserve compatibility with the standard | ||
2346 | * serial driver. | ||
2347 | */ | ||
2348 | |||
2349 | write_lock_irqsave(&pB->read_fifo_spinlock, flags); | ||
2350 | cnow = pCh->icount; | ||
2351 | write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); | ||
2352 | |||
2353 | icount->cts = cnow.cts; | ||
2354 | icount->dsr = cnow.dsr; | ||
2355 | icount->rng = cnow.rng; | ||
2356 | icount->dcd = cnow.dcd; | ||
2357 | icount->rx = cnow.rx; | ||
2358 | icount->tx = cnow.tx; | ||
2359 | icount->frame = cnow.frame; | ||
2360 | icount->overrun = cnow.overrun; | ||
2361 | icount->parity = cnow.parity; | ||
2362 | icount->brk = cnow.brk; | ||
2363 | icount->buf_overrun = cnow.buf_overrun; | ||
2364 | return 0; | ||
2365 | } | ||
2366 | |||
2353 | /******************************************************************************/ | 2367 | /******************************************************************************/ |
2354 | /* Function: GetSerialInfo() */ | 2368 | /* Function: GetSerialInfo() */ |
2355 | /* Parameters: Pointer to channel structure */ | 2369 | /* Parameters: Pointer to channel structure */ |