Commit e8770484 authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

USB: ftdi_sio: clean up SIO write support

The original SIO devices require a control byte for every packet
written. Clean up the unnecessarily messy implementation of this.
Signed-off-by: default avatarJohan Hovold <jhovold@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent d3901a06
...@@ -71,10 +71,6 @@ struct ftdi_private { ...@@ -71,10 +71,6 @@ struct ftdi_private {
/* the last data state set - needed for doing /* the last data state set - needed for doing
* a break * a break
*/ */
int write_offset; /* This is the offset in the usb data block to
* write the serial data - it varies between
* devices
*/
int flags; /* some ASYNC_xxxx flags are supported */ int flags; /* some ASYNC_xxxx flags are supported */
unsigned long last_dtr_rts; /* saved modem control outputs */ unsigned long last_dtr_rts; /* saved modem control outputs */
wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
...@@ -1279,7 +1275,6 @@ static void ftdi_determine_type(struct usb_serial_port *port) ...@@ -1279,7 +1275,6 @@ static void ftdi_determine_type(struct usb_serial_port *port)
/* Assume it is not the original SIO device for now. */ /* Assume it is not the original SIO device for now. */
priv->baud_base = 48000000 / 2; priv->baud_base = 48000000 / 2;
priv->write_offset = 0;
version = le16_to_cpu(udev->descriptor.bcdDevice); version = le16_to_cpu(udev->descriptor.bcdDevice);
interfaces = udev->actconfig->desc.bNumInterfaces; interfaces = udev->actconfig->desc.bNumInterfaces;
...@@ -1321,7 +1316,6 @@ static void ftdi_determine_type(struct usb_serial_port *port) ...@@ -1321,7 +1316,6 @@ static void ftdi_determine_type(struct usb_serial_port *port)
/* Old device. Assume it's the original SIO. */ /* Old device. Assume it's the original SIO. */
priv->chip_type = SIO; priv->chip_type = SIO;
priv->baud_base = 12000000 / 16; priv->baud_base = 12000000 / 16;
priv->write_offset = 1;
} else if (version < 0x400) { } else if (version < 0x400) {
/* Assume it's an FT8U232AM (or FT8U245AM) */ /* Assume it's an FT8U232AM (or FT8U245AM) */
/* (It might be a BM because of the iSerialNumber bug, /* (It might be a BM because of the iSerialNumber bug,
...@@ -1757,50 +1751,29 @@ static int ftdi_prepare_write_buffer(struct usb_serial_port *port, ...@@ -1757,50 +1751,29 @@ static int ftdi_prepare_write_buffer(struct usb_serial_port *port,
{ {
struct ftdi_private *priv; struct ftdi_private *priv;
unsigned char *buffer; unsigned char *buffer;
int data_offset ; /* will be 1 for the SIO and 0 otherwise */ int len;
int transfer_size;
priv = usb_get_serial_port_data(port); priv = usb_get_serial_port_data(port);
data_offset = priv->write_offset; len = count;
dbg("data_offset set to %d", data_offset); if (priv->chip_type == SIO && count != 0)
len += ((count - 1) / (priv->max_packet_size - 1)) + 1;
/* Determine total transfer size */ buffer = kmalloc(len, GFP_ATOMIC);
transfer_size = count;
if (data_offset > 0) {
/* Original sio needs control bytes too... */
transfer_size += (data_offset *
((count + (priv->max_packet_size - 1 - data_offset)) /
(priv->max_packet_size - data_offset)));
}
buffer = kmalloc(transfer_size, GFP_ATOMIC);
if (!buffer) { if (!buffer) {
dev_err(&port->dev, "%s - could not allocate buffer\n", dev_err(&port->dev, "%s - could not allocate buffer\n",
__func__); __func__);
return -ENOMEM; return -ENOMEM;
} }
/* Copy data */ if (priv->chip_type == SIO) {
if (data_offset > 0) { int i, msg_len;
/* Original sio requires control byte at start of
each packet. */ for (i = 0; i < len; i += priv->max_packet_size) {
int user_pktsz = priv->max_packet_size - data_offset; msg_len = min_t(int, len - i, priv->max_packet_size) - 1;
int todo = count; buffer[i] = (msg_len << 2) + 1;
unsigned char *first_byte = buffer; memcpy(&buffer[i + 1], src, msg_len);
const unsigned char *current_position = src; src += msg_len;
while (todo > 0) {
if (user_pktsz > todo)
user_pktsz = todo;
/* Write the control byte at the front of the packet*/
*first_byte = 1 | ((user_pktsz) << 2);
/* Copy data for packet */
memcpy(first_byte + data_offset,
current_position, user_pktsz);
first_byte += user_pktsz + data_offset;
current_position += user_pktsz;
todo -= user_pktsz;
} }
} else { } else {
memcpy(buffer, src, count); memcpy(buffer, src, count);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment