Re: [PATCH] cdc-acm: implement TIOCSSERIAL to avoid blocking close(2)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 08/11/12 19:47, Dan Williams wrote:
> Some devices (ex Nokia C7) simply don't respond at all when data is
> sent to some of their USB interfaces.  The data gets stuck in the
> TTYs queue and sits there until close(2), which them blocks because
> closing_wait defaults to 30 seconds (even though the fd is
> O_NONBLOCK).  This is rarely desired.  Implement the standard
> mechanism to adjust closing_wait and let applications handle it how
> they want to.
> 
> See also 02303f73373aa1da19dbec510ec5a4e2576f9610 for usb_wwan.c.
> 
> Signed-off-by: Dan Williams <dcbw@xxxxxxxxxx> Cc:
> stable@xxxxxxxxxxxxxxx

Works pretty well for me.

Tested-by: Aleksander Morgado <aleksander@xxxxxxx>


> --- drivers/usb/class/cdc-acm.c | 38
> ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38
> insertions(+)
> 
> diff --git a/drivers/usb/class/cdc-acm.c
> b/drivers/usb/class/cdc-acm.c index 6e49ec6..8d809a8 100644 ---
> a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@
> -787,6 +787,10 @@ static int get_serial_info(struct acm *acm,
> struct serial_struct __user *info) tmp.flags = ASYNC_LOW_LATENCY; 
> tmp.xmit_fifo_size = acm->writesize; tmp.baud_base =
> le32_to_cpu(acm->line.dwDTERate); +	tmp.close_delay	=
> acm->port.close_delay / 10; +	tmp.closing_wait =
> acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? +
> ASYNC_CLOSING_WAIT_NONE : +				acm->port.closing_wait / 10;
> 
> if (copy_to_user(info, &tmp, sizeof(tmp))) return -EFAULT; @@
> -794,6 +798,37 @@ static int get_serial_info(struct acm *acm,
> struct serial_struct __user *info) return 0; }
> 
> +static int set_serial_info(struct acm *acm, +				struct
> serial_struct __user *newinfo) +{ +	struct serial_struct
> new_serial; +	unsigned int closing_wait, close_delay; +	int retval
> = 0; + +	if (copy_from_user(&new_serial, newinfo,
> sizeof(new_serial))) +		return -EFAULT; + +	close_delay =
> new_serial.close_delay * 10; +	closing_wait =
> new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? +
> ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10; + +
> mutex_lock(&acm->port.mutex); + +	if (!capable(CAP_SYS_ADMIN)) { +
> if ((close_delay != acm->port.close_delay) || +		    (closing_wait
> != acm->port.closing_wait)) +			retval = -EPERM; +		else +			retval
> = -EOPNOTSUPP; +	} else { +		acm->port.close_delay  = close_delay; 
> +		acm->port.closing_wait = closing_wait; +	} + +
> mutex_unlock(&acm->port.mutex); +	return retval; +} + static int
> acm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned
> long arg) { @@ -804,6 +839,9 @@ static int acm_tty_ioctl(struct
> tty_struct *tty, case TIOCGSERIAL: /* gets serial port data */ rv =
> get_serial_info(acm, (struct serial_struct __user *) arg); break; +
> case TIOCSSERIAL: +		rv = set_serial_info(acm, (struct
> serial_struct __user *) arg); +		break; }
> 
> return rv;
> 


- -- 
Aleksander
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://www.enigmail.net/

iEYEARECAAYFAlCb/0kACgkQgxIgkKLogl7Z7wCdHR3ydnlfHjK5gtMNjjUMfBu9
KCkAoIfo+ZekWkZmW6MDj1KNJTcFUn95
=nxmZ
-----END PGP SIGNATURE-----
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux