Re: USB: serial: mct_usb232: add drain on close

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

 



On Fri, Jan 22, 2010 at 02:21:12PM -0700, Pete Zaitcev wrote:
> I ran the following test:
> 
>   while true; do echo -n "01234567890abcdefghij" >/dev/ttyUSB0; done
> 
> The data is sent over the serial line with random loss. It occurs because
> 1. when echo closes ttyUSB0, there's a chance that it cancels the write URB.
> 2. MCT U232 buffers the last character and acks the USB data before the
>    serial bits are completely sent out.
> 
> This was originally reported in Red Hat Linux bug #170490.
> 
> The fix relies on modern facilities drain_delay (approximately the
> number of bytes outstanding, see case #2 above) and chars_in_buffer.
> The latter did not account for the last buffer that was removed
> from the kfifo but not completed yet. I considered it a bug and
> changed it.
> 
> The test above works as expected with this patch applied.
> 
> Signed-off-by: Pete Zaitcev <zaitcev@xxxxxxxxxx>
> 
> ---
>  drivers/usb/serial/generic.c  |    7 +++++--
>  drivers/usb/serial/mct_u232.c |    3 +++
>  2 files changed, 8 insertions(+), 2 deletions(-)
> 
> This is a resend due to misapplication. Should not fuzz this time!
> 
> diff -urp -X dontdiff linux-2.6-gregkh/drivers/usb/serial/generic.c linux-2.6-tip/drivers/usb/serial/generic.c
> --- linux-2.6-gregkh/drivers/usb/serial/generic.c	2010-01-22 13:50:50.433875777 -0700
> +++ linux-2.6-tip/drivers/usb/serial/generic.c	2010-01-05 11:32:02.346260069 -0700
> @@ -387,10 +387,13 @@ int usb_serial_generic_chars_in_buffer(s
>  	dbg("%s - port %d", __func__, port->number);
>  
>  	spin_lock_irqsave(&port->lock, flags);
> -	if (serial->type->max_in_flight_urbs)
> +	if (serial->type->max_in_flight_urbs) {

Superfluous {.

>  		chars = port->tx_bytes_flight;
> -	else if (serial->num_bulk_out)
> +	} else if (serial->num_bulk_out) {
> +		/* This overcounts badly, but is good enough for drain wait. */
>  		chars = kfifo_len(&port->write_fifo);
> +		chars += port->write_urb_busy * port->bulk_out_size;
> +	}
>  	spin_unlock_irqrestore(&port->lock, flags);
>  
>  	dbg("%s - returns %d", __func__, chars);
> diff -urp -X dontdiff linux-2.6-gregkh/drivers/usb/serial/mct_u232.c linux-2.6-tip/drivers/usb/serial/mct_u232.c
> --- linux-2.6-gregkh/drivers/usb/serial/mct_u232.c	2010-01-22 13:50:50.446875757 -0700
> +++ linux-2.6-tip/drivers/usb/serial/mct_u232.c	2009-12-07 20:18:13.649078959 -0700
> @@ -547,8 +540,11 @@ static void mct_u232_dtr_rts(struct usb_
>  
>  static void mct_u232_close(struct usb_serial_port *port)
>  {
> +

White space error.

>  	dbg("%s port %d", __func__, port->number);
>  
> +	port->port.drain_delay = 2;
> +

You need to set drain_delay in open rather than close, as drain wait is
done before driver-specific close is called (see tty_port_close).

>  	if (port->serial->dev) {
>  		/* shutdown our urbs */
>  		usb_kill_urb(port->write_urb);

With those changes in place,

Acked-by: Johan Hovold <jhovold@xxxxxxxxx>

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