diff options
-rw-r--r-- | drivers/usb/serial/safe_serial.c | 143 |
1 files changed, 32 insertions, 111 deletions
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 43a0cadd578..915c094ef92 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -1,6 +1,7 @@ /* * Safe Encapsulated USB Serial Driver * + * Copyright (C) 2010 Johan Hovold <jhovold@gmail.com> * Copyright (C) 2001 Lineo * Copyright (C) 2001 Hewlett-Packard * @@ -84,8 +85,8 @@ static int debug; static int safe = 1; static int padded = CONFIG_USB_SERIAL_SAFE_PADDED; -#define DRIVER_VERSION "v0.0b" -#define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com" +#define DRIVER_VERSION "v0.1" +#define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com, Johan Hovold <jhovold@gmail.com>" #define DRIVER_DESC "USB Safe Encapsulated Serial" MODULE_AUTHOR(DRIVER_AUTHOR); @@ -284,119 +285,40 @@ static void safe_read_bulk_callback(struct urb *urb) /* FIXME: Need a mechanism to retry later if this happens */ } -static int safe_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) +static int safe_prepare_write_buffer(struct usb_serial_port *port, + void *dest, size_t size) { - unsigned char *data; - int result; - int i; - int packet_length; - - dbg("safe_write port: %p %d urb: %p count: %d", - port, port->number, port->write_urb, count); - - if (!port->write_urb) { - dbg("%s - write urb NULL", __func__); - return 0; - } - - dbg("safe_write write_urb: %d transfer_buffer_length", - port->write_urb->transfer_buffer_length); - - if (!port->write_urb->transfer_buffer_length) { - dbg("%s - write urb transfer_buffer_length zero", __func__); - return 0; - } - if (count == 0) { - dbg("%s - write request of 0 bytes", __func__); - return 0; - } - spin_lock_bh(&port->lock); - if (port->write_urb_busy) { - spin_unlock_bh(&port->lock); - dbg("%s - already writing", __func__); - return 0; - } - port->write_urb_busy = 1; - spin_unlock_bh(&port->lock); - - packet_length = port->bulk_out_size; /* get max packetsize */ - - i = packet_length - (safe ? 2 : 0); /* get bytes to send */ - count = (count > i) ? i : count; - - - /* get the data into the transfer buffer */ - data = port->write_urb->transfer_buffer; - memset(data, '0', packet_length); - - memcpy(data, buf, count); - - if (safe) { - __u16 fcs; - - /* pad if necessary */ - if (!padded) - packet_length = count + 2; - /* set count */ - data[packet_length - 2] = count << 2; - data[packet_length - 1] = 0; - - /* compute fcs and insert into trailer */ - fcs = fcs_compute10(data, packet_length, CRC10_INITFCS); - data[packet_length - 2] |= fcs >> 8; - data[packet_length - 1] |= fcs & 0xff; - - /* set length to send */ - port->write_urb->transfer_buffer_length = packet_length; + unsigned char *buf = dest; + int count; + int trailer_len; + int pkt_len; + __u16 fcs; + + trailer_len = safe ? 2 : 0; + + count = kfifo_out_locked(&port->write_fifo, buf, size - trailer_len, + &port->lock); + if (!safe) + return count; + + /* pad if necessary */ + if (padded) { + pkt_len = size; + memset(buf + count, '0', pkt_len - count - trailer_len); } else { - port->write_urb->transfer_buffer_length = count; - } - - usb_serial_debug_data(debug, &port->dev, __func__, count, - port->write_urb->transfer_buffer); -#ifdef ECHO_TX - { - int i; - unsigned char *cp = port->write_urb->transfer_buffer; - for (i = 0; i < port->write_urb->transfer_buffer_length; i++) { - if ((i % 32) == 0) - printk("\nsu[%02x] ", i); - printk("%02x ", *cp++); - } - printk("\n"); + pkt_len = count + trailer_len; } -#endif - port->write_urb->dev = port->serial->dev; - result = usb_submit_urb(port->write_urb, GFP_KERNEL); - if (result) { - port->write_urb_busy = 0; - dev_err(&port->dev, - "%s - failed submitting write urb, error %d\n", - __func__, result); - return 0; - } - dbg("%s urb: %p submitted", __func__, port->write_urb); - return count; -} - -static int safe_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - int room = 0; /* Default: no room */ - unsigned long flags; - - dbg("%s", __func__); + /* set count */ + buf[pkt_len - 2] = count << 2; + buf[pkt_len - 1] = 0; - spin_lock_irqsave(&port->lock, flags); - if (port->write_urb_busy) - room = port->bulk_out_size - (safe ? 2 : 0); - spin_unlock_irqrestore(&port->lock, flags); + /* compute fcs and insert into trailer */ + fcs = fcs_compute10(buf, pkt_len, CRC10_INITFCS); + buf[pkt_len - 2] |= fcs >> 8; + buf[pkt_len - 1] |= fcs & 0xff; - if (room) - dbg("safe_write_room returns %d", room); - return room; + return pkt_len; } static int safe_startup(struct usb_serial *serial) @@ -421,9 +343,8 @@ static struct usb_serial_driver safe_device = { .id_table = id_table, .usb_driver = &safe_driver, .num_ports = 1, - .write = safe_write, - .write_room = safe_write_room, .read_bulk_callback = safe_read_bulk_callback, + .prepare_write_buffer = safe_prepare_write_buffer, .attach = safe_startup, }; |