From bbcb2b907415a90334521a31a8767cd77462c716 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 17 Mar 2010 23:00:37 +0100 Subject: [PATCH] USB: serial: allow drivers to define bulk buffer sizes Allow drivers to define custom bulk in/out buffer sizes in struct usb_serial_driver. If not set, fall back to the default buffer size which matches the endpoint size. Three drivers are currently freeing the pre-allocated buffers and allocating larger ones to achieve this at port probe (ftdi_sio) or even at port open (ipaq and iuu_phoenix), which needless to say is suboptimal. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 16 +--------------- drivers/usb/serial/ipaq.c | 28 ++-------------------------- drivers/usb/serial/iuu_phoenix.c | 30 ++---------------------------- drivers/usb/serial/usb-serial.c | 8 ++++++-- include/linux/usb/serial.h | 5 +++++ 5 files changed, 16 insertions(+), 71 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 46a88ae9c46a..ab4ad18d6ef3 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -768,9 +768,6 @@ static const char *ftdi_chip_name[] = { }; -/* Constants for read urb and write urb */ -#define BUFSZ 512 - /* Used for TIOCMIWAIT */ #define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD) #define FTDI_STATUS_B1_MASK (FTDI_RS_BI) @@ -821,6 +818,7 @@ static struct usb_serial_driver ftdi_sio_device = { .usb_driver = &ftdi_driver, .id_table = id_table_combined, .num_ports = 1, + .bulk_in_size = 512, .probe = ftdi_sio_probe, .port_probe = ftdi_sio_port_probe, .port_remove = ftdi_sio_port_remove, @@ -1552,18 +1550,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) if (quirk && quirk->port_probe) quirk->port_probe(priv); - /* Increase the size of read buffers */ - kfree(port->bulk_in_buffer); - port->bulk_in_buffer = kmalloc(BUFSZ, GFP_KERNEL); - if (!port->bulk_in_buffer) { - kfree(priv); - return -ENOMEM; - } - if (port->read_urb) { - port->read_urb->transfer_buffer = port->bulk_in_buffer; - port->read_urb->transfer_buffer_length = BUFSZ; - } - priv->port = port; /* Free port's existing write urb and transfer buffer. */ diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 3fea9298eb15..87b11461bf11 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -571,6 +571,8 @@ static struct usb_serial_driver ipaq_device = { .description = "PocketPC PDA", .usb_driver = &ipaq_driver, .id_table = ipaq_id_table, + .bulk_in_size = URBDATA_SIZE, + .bulk_out_size = URBDATA_SIZE, .open = ipaq_open, .close = ipaq_close, .attach = ipaq_startup, @@ -628,32 +630,6 @@ static int ipaq_open(struct tty_struct *tty, priv->free_len += PACKET_SIZE; } - /* - * Lose the small buffers usbserial provides. Make larger ones. - */ - - kfree(port->bulk_in_buffer); - kfree(port->bulk_out_buffer); - /* make sure the generic serial code knows */ - port->bulk_out_buffer = NULL; - - port->bulk_in_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); - if (port->bulk_in_buffer == NULL) - goto enomem; - - port->bulk_out_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); - if (port->bulk_out_buffer == NULL) { - /* the buffer is useless, free it */ - kfree(port->bulk_in_buffer); - port->bulk_in_buffer = NULL; - goto enomem; - } - port->read_urb->transfer_buffer = port->bulk_in_buffer; - port->write_urb->transfer_buffer = port->bulk_out_buffer; - port->read_urb->transfer_buffer_length = URBDATA_SIZE; - port->bulk_out_size = port->write_urb->transfer_buffer_length - = URBDATA_SIZE; - msleep(1000*initial_wait); /* diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 43f13cf2f016..74551cb2e8ee 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -1044,34 +1044,6 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) if (buf == NULL) return -ENOMEM; - /* fixup the endpoint buffer size */ - kfree(port->bulk_out_buffer); - port->bulk_out_buffer = kmalloc(512, GFP_KERNEL); - port->bulk_out_size = 512; - kfree(port->bulk_in_buffer); - port->bulk_in_buffer = kmalloc(512, GFP_KERNEL); - port->bulk_in_size = 512; - - if (!port->bulk_out_buffer || !port->bulk_in_buffer) { - kfree(port->bulk_out_buffer); - kfree(port->bulk_in_buffer); - kfree(buf); - return -ENOMEM; - } - - usb_fill_bulk_urb(port->write_urb, port->serial->dev, - usb_sndbulkpipe(port->serial->dev, - port->bulk_out_endpointAddress), - port->bulk_out_buffer, 512, - NULL, NULL); - - - usb_fill_bulk_urb(port->read_urb, port->serial->dev, - usb_rcvbulkpipe(port->serial->dev, - port->bulk_in_endpointAddress), - port->bulk_in_buffer, 512, - NULL, NULL); - priv->poll = 0; /* initialize writebuf */ @@ -1277,6 +1249,8 @@ static struct usb_serial_driver iuu_device = { }, .id_table = id_table, .num_ports = 1, + .bulk_in_size = 512, + .bulk_out_size = 512, .port_probe = iuu_create_sysfs_attrs, .port_remove = iuu_remove_sysfs_attrs, .open = iuu_open, diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index f3f65171de38..538924627eba 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -901,7 +901,9 @@ int usb_serial_probe(struct usb_interface *interface, dev_err(&interface->dev, "No free urbs available\n"); goto probe_error; } - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); + buffer_size = serial->type->bulk_in_size; + if (!buffer_size) + buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); port->bulk_in_size = buffer_size; port->bulk_in_endpointAddress = endpoint->bEndpointAddress; port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); @@ -927,7 +929,9 @@ int usb_serial_probe(struct usb_interface *interface, } if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL)) goto probe_error; - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); + buffer_size = serial->type->bulk_out_size; + if (!buffer_size) + buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); port->bulk_out_size = buffer_size; port->bulk_out_endpointAddress = endpoint->bEndpointAddress; port->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index b7682fed1d9c..ab311dab3383 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -179,6 +179,8 @@ static inline void usb_set_serial_data(struct usb_serial *serial, void *data) * @id_table: pointer to a list of usb_device_id structures that define all * of the devices this structure can support. * @num_ports: the number of different ports this device will have. + * @bulk_in_size: bytes to allocate for bulk-in buffer (0 = end-point size) + * @bulk_out_size: bytes to allocate for bulk-out buffer (0 = end-point size) * @calc_num_ports: pointer to a function to determine how many ports this * device has dynamically. It will be called after the probe() * callback is called, but before attach() @@ -223,6 +225,9 @@ struct usb_serial_driver { struct usb_dynids dynids; int max_in_flight_urbs; + size_t bulk_in_size; + size_t bulk_out_size; + int (*probe)(struct usb_serial *serial, const struct usb_device_id *id); int (*attach)(struct usb_serial *serial); int (*calc_num_ports) (struct usb_serial *serial); -- GitLab