Hello, The TIOCOUTQ ioctl calls chars_in_buffer(), and some apps depend on a correct behaviour of that. mos7840 implements it wrongly: if you write just one char, TIOCOUTQ will return 32. The attached patch should fix it. But it is not tested: customer reported the problem and fails to test the patch. Please review. https://bugzilla.kernel.org/show_bug.cgi?id=45791 Signed-off-by: Stas Sergeev <stsp@xxxxxxxxxxxxxxxxxxxxx>
From 02804e64f786d6aaaba54933f7cadd10dff2f497 Mon Sep 17 00:00:00 2001 From: Stas Sergeev <stsp@users.sourceforge.net> Date: Mon, 23 Jul 2012 13:17:40 +0400 Subject: [PATCH] mos7840: fix chars_in_buffer --- drivers/usb/serial/mos7840.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 57eca24..440d7f8 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -243,7 +243,7 @@ struct moschip_port { spinlock_t pool_lock; struct urb *write_urb_pool[NUM_URBS]; - char busy[NUM_URBS]; + int busy[NUM_URBS]; bool read_urb_busy; /* For device(s) with LED indicator */ @@ -1234,7 +1234,7 @@ static int mos7840_chars_in_buffer(struct tty_struct *tty) spin_lock_irqsave(&mos7840_port->pool_lock, flags); for (i = 0; i < NUM_URBS; ++i) if (mos7840_port->busy[i]) - chars += URB_TRANSFER_BUFFER_SIZE; + chars += mos7840_port->busy[i]; spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); dbg("%s - returns %d", __func__, chars); return chars; @@ -1531,10 +1531,11 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, /* try to find a free urb in the list */ urb = NULL; + transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE); spin_lock_irqsave(&mos7840_port->pool_lock, flags); for (i = 0; i < NUM_URBS; ++i) { if (!mos7840_port->busy[i]) { - mos7840_port->busy[i] = 1; + mos7840_port->busy[i] = transfer_size; urb = mos7840_port->write_urb_pool[i]; dbg("URB:%d", i); break; @@ -1557,7 +1558,6 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, goto exit; } } - transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE); memcpy(urb->transfer_buffer, current_position, transfer_size); -- 1.7.4.4