@@ -2328,6 +2328,8 @@ static int ftdi_ioctl(struct tty_struct *tty,
2328
2328
{
2329
2329
struct usb_serial_port * port = tty -> driver_data ;
2330
2330
struct ftdi_private * priv = usb_get_serial_port_data (port );
2331
+ struct async_icount cnow ;
2332
+ struct async_icount cprev ;
2331
2333
2332
2334
dbg ("%s cmd 0x%04x" , __func__ , cmd );
2333
2335
@@ -2347,41 +2349,30 @@ static int ftdi_ioctl(struct tty_struct *tty,
2347
2349
* - mask passed in arg for lines of interest
2348
2350
* (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
2349
2351
* Caller should use TIOCGICOUNT to see which one it was.
2350
- * (except that the driver doesn't support it !)
2351
2352
*
2352
2353
* This code is borrowed from linux/drivers/char/serial.c
2353
2354
*/
2354
2355
case TIOCMIWAIT :
2355
- while (priv != NULL ) {
2356
+ cprev = priv -> icount ;
2357
+ while (1 ) {
2356
2358
interruptible_sleep_on (& priv -> delta_msr_wait );
2357
2359
/* see if a signal did it */
2358
2360
if (signal_pending (current ))
2359
2361
return - ERESTARTSYS ;
2360
- else {
2361
- char diff = priv -> diff_status ;
2362
-
2363
- if (diff == 0 )
2364
- return - EIO ; /* no change => error */
2365
-
2366
- /* Consume all events */
2367
- priv -> diff_status = 0 ;
2368
-
2369
- /* Return 0 if caller wanted to know about
2370
- these bits */
2371
- if (((arg & TIOCM_RNG ) && (diff & FTDI_RS0_RI )) ||
2372
- ((arg & TIOCM_DSR ) && (diff & FTDI_RS0_DSR )) ||
2373
- ((arg & TIOCM_CD ) && (diff & FTDI_RS0_RLSD )) ||
2374
- ((arg & TIOCM_CTS ) && (diff & FTDI_RS0_CTS ))) {
2375
- return 0 ;
2376
- }
2377
- /*
2378
- * Otherwise caller can't care less about what
2379
- * happened,and so we continue to wait for more
2380
- * events.
2381
- */
2362
+ cnow = priv -> icount ;
2363
+ if (cnow .rng == cprev .rng && cnow .dsr == cprev .dsr &&
2364
+ cnow .dcd == cprev .dcd && cnow .cts == cprev .cts )
2365
+ return - EIO ; /* no change => error */
2366
+ if (((arg & TIOCM_RNG ) && (cnow .rng != cprev .rng )) ||
2367
+ ((arg & TIOCM_DSR ) && (cnow .dsr != cprev .dsr )) ||
2368
+ ((arg & TIOCM_CD ) && (cnow .dcd != cprev .dcd )) ||
2369
+ ((arg & TIOCM_CTS ) && (cnow .cts != cprev .cts ))) {
2370
+ return 0 ;
2382
2371
}
2372
+ cprev = cnow ;
2383
2373
}
2384
- return 0 ;
2374
+ /* not reached */
2375
+ break ;
2385
2376
case TIOCSERGETLSR :
2386
2377
return get_lsr_info (port , (struct serial_struct __user * )arg );
2387
2378
break ;
0 commit comments