-----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