USB: serial: re-implement multi-urb writes in generic driver

Use dynamic transfer buffer sizes since it is more efficient to let the
host controller do the partitioning to fit endpoint size. This way we
also do not use more than one urb per write request.

Replace max_in_flight_urbs with multi_urb_write flag in struct
usb_serial_driver to enable multi-urb writes.

Use MAX_TX_URBS=40 and a max buffer size of PAGE_SIZE to prevent DoS
attacks.

Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index ff8872e..2a32837 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -60,6 +60,8 @@
  * @write_urb: pointer to the bulk out struct urb for this port.
  * @write_fifo: kfifo used to buffer outgoing data
  * @write_urb_busy: port`s writing status
+ * @tx_bytes: number of bytes currently in host stack queues
+ * @tx_urbs: number of urbs currently in host stack queues
  * @bulk_out_endpointAddress: endpoint address for the bulk out pipe for this
  *	port.
  * @write_wait: a wait_queue_head_t used by the port.
@@ -98,8 +100,8 @@
 	int			write_urb_busy;
 	__u8			bulk_out_endpointAddress;
 
-	int			tx_bytes_flight;
-	int			urbs_in_flight;
+	int			tx_bytes;
+	int			tx_urbs;
 
 	wait_queue_head_t	write_wait;
 	struct work_struct	work;
@@ -223,7 +225,8 @@
 	struct device_driver	driver;
 	struct usb_driver	*usb_driver;
 	struct usb_dynids	dynids;
-	int			max_in_flight_urbs;
+
+	unsigned char		multi_urb_write:1;
 
 	size_t			bulk_in_size;
 	size_t			bulk_out_size;