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 <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
317149c655
commit
bbcb2b9074
@@ -768,9 +768,6 @@ static const char *ftdi_chip_name[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Constants for read urb and write urb */
|
|
||||||
#define BUFSZ 512
|
|
||||||
|
|
||||||
/* Used for TIOCMIWAIT */
|
/* Used for TIOCMIWAIT */
|
||||||
#define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD)
|
#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)
|
#define FTDI_STATUS_B1_MASK (FTDI_RS_BI)
|
||||||
@@ -821,6 +818,7 @@ static struct usb_serial_driver ftdi_sio_device = {
|
|||||||
.usb_driver = &ftdi_driver,
|
.usb_driver = &ftdi_driver,
|
||||||
.id_table = id_table_combined,
|
.id_table = id_table_combined,
|
||||||
.num_ports = 1,
|
.num_ports = 1,
|
||||||
|
.bulk_in_size = 512,
|
||||||
.probe = ftdi_sio_probe,
|
.probe = ftdi_sio_probe,
|
||||||
.port_probe = ftdi_sio_port_probe,
|
.port_probe = ftdi_sio_port_probe,
|
||||||
.port_remove = ftdi_sio_port_remove,
|
.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)
|
if (quirk && quirk->port_probe)
|
||||||
quirk->port_probe(priv);
|
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;
|
priv->port = port;
|
||||||
|
|
||||||
/* Free port's existing write urb and transfer buffer. */
|
/* Free port's existing write urb and transfer buffer. */
|
||||||
|
@@ -571,6 +571,8 @@ static struct usb_serial_driver ipaq_device = {
|
|||||||
.description = "PocketPC PDA",
|
.description = "PocketPC PDA",
|
||||||
.usb_driver = &ipaq_driver,
|
.usb_driver = &ipaq_driver,
|
||||||
.id_table = ipaq_id_table,
|
.id_table = ipaq_id_table,
|
||||||
|
.bulk_in_size = URBDATA_SIZE,
|
||||||
|
.bulk_out_size = URBDATA_SIZE,
|
||||||
.open = ipaq_open,
|
.open = ipaq_open,
|
||||||
.close = ipaq_close,
|
.close = ipaq_close,
|
||||||
.attach = ipaq_startup,
|
.attach = ipaq_startup,
|
||||||
@@ -628,32 +630,6 @@ static int ipaq_open(struct tty_struct *tty,
|
|||||||
priv->free_len += PACKET_SIZE;
|
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);
|
msleep(1000*initial_wait);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -1044,34 +1044,6 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return -ENOMEM;
|
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;
|
priv->poll = 0;
|
||||||
|
|
||||||
/* initialize writebuf */
|
/* initialize writebuf */
|
||||||
@@ -1277,6 +1249,8 @@ static struct usb_serial_driver iuu_device = {
|
|||||||
},
|
},
|
||||||
.id_table = id_table,
|
.id_table = id_table,
|
||||||
.num_ports = 1,
|
.num_ports = 1,
|
||||||
|
.bulk_in_size = 512,
|
||||||
|
.bulk_out_size = 512,
|
||||||
.port_probe = iuu_create_sysfs_attrs,
|
.port_probe = iuu_create_sysfs_attrs,
|
||||||
.port_remove = iuu_remove_sysfs_attrs,
|
.port_remove = iuu_remove_sysfs_attrs,
|
||||||
.open = iuu_open,
|
.open = iuu_open,
|
||||||
|
@@ -901,7 +901,9 @@ int usb_serial_probe(struct usb_interface *interface,
|
|||||||
dev_err(&interface->dev, "No free urbs available\n");
|
dev_err(&interface->dev, "No free urbs available\n");
|
||||||
goto probe_error;
|
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_size = buffer_size;
|
||||||
port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
|
port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
|
||||||
port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
|
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))
|
if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL))
|
||||||
goto probe_error;
|
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_size = buffer_size;
|
||||||
port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
|
port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
|
||||||
port->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
|
port->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
|
||||||
|
@@ -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
|
* @id_table: pointer to a list of usb_device_id structures that define all
|
||||||
* of the devices this structure can support.
|
* of the devices this structure can support.
|
||||||
* @num_ports: the number of different ports this device will have.
|
* @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
|
* @calc_num_ports: pointer to a function to determine how many ports this
|
||||||
* device has dynamically. It will be called after the probe()
|
* device has dynamically. It will be called after the probe()
|
||||||
* callback is called, but before attach()
|
* callback is called, but before attach()
|
||||||
@@ -223,6 +225,9 @@ struct usb_serial_driver {
|
|||||||
struct usb_dynids dynids;
|
struct usb_dynids dynids;
|
||||||
int max_in_flight_urbs;
|
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 (*probe)(struct usb_serial *serial, const struct usb_device_id *id);
|
||||||
int (*attach)(struct usb_serial *serial);
|
int (*attach)(struct usb_serial *serial);
|
||||||
int (*calc_num_ports) (struct usb_serial *serial);
|
int (*calc_num_ports) (struct usb_serial *serial);
|
||||||
|
Reference in New Issue
Block a user