summaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/usb-serial.c
diff options
context:
space:
mode:
authorDavid VomLehn <dvomlehn@cisco.com>2009-08-28 12:54:27 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-23 06:46:34 -0700
commit8e8dce065088833fc418bfa5fbf035cb0726c04c (patch)
tree146ad73ff1ee9439263678c5493a5c2d180ad794 /drivers/usb/serial/usb-serial.c
parent74aee796c613f54e9f089170df548c0b3f15af69 (diff)
downloadblackbird-op-linux-8e8dce065088833fc418bfa5fbf035cb0726c04c.tar.gz
blackbird-op-linux-8e8dce065088833fc418bfa5fbf035cb0726c04c.zip
USB: use kfifo to buffer usb-generic serial writes
When do_output_char() attempts to write a carriage return/line feed sequence, it first checks to see how much buffer room is available. If there are at least two characters free, it will write the carriage return/line feed with two calls to tty_put_char(). It calls the tty_operation functions write() for devices that don't support the tty_operations function put_char(). If the USB generic serial device's write URB is not in use, it will return the buffer size when asked how much room is available. The write() of the carriage return will cause it to mark the write URB busy, so the subsequent write() of the line feed will be ignored. This patch uses the kfifo infrastructure to implement a write FIFO that accurately returns the amount of space available in the buffer. Signed-off-by: David VomLehn <dvomlehn@cisco.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r--drivers/usb/serial/usb-serial.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 45975b4984ea..ff75a3589e7e 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -35,6 +35,7 @@
#include <linux/serial.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
+#include <linux/kfifo.h>
#include "pl2303.h"
/*
@@ -625,6 +626,8 @@ static void port_release(struct device *dev)
usb_free_urb(port->write_urb);
usb_free_urb(port->interrupt_in_urb);
usb_free_urb(port->interrupt_out_urb);
+ if (!IS_ERR(port->write_fifo) && port->write_fifo)
+ kfifo_free(port->write_fifo);
kfree(port->bulk_in_buffer);
kfree(port->bulk_out_buffer);
kfree(port->interrupt_in_buffer);
@@ -964,6 +967,10 @@ int usb_serial_probe(struct usb_interface *interface,
dev_err(&interface->dev, "No free urbs available\n");
goto probe_error;
}
+ port->write_fifo = kfifo_alloc(PAGE_SIZE, GFP_KERNEL,
+ &port->lock);
+ if (IS_ERR(port->write_fifo))
+ goto probe_error;
buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
port->bulk_out_size = buffer_size;
port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
OpenPOWER on IntegriCloud