|
@@ -1,6 +1,7 @@
|
|
|
/*
|
|
|
* KLSI KL5KUSB105 chip RS232 converter driver
|
|
|
*
|
|
|
+ * Copyright (C) 2010 Johan Hovold <jhovold@gmail.com>
|
|
|
* Copyright (C) 2001 Utz-Uwe Haus <haus@uuhaus.de>
|
|
|
*
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
@@ -34,17 +35,6 @@
|
|
|
* implement handshaking or decide that we do not support it
|
|
|
*/
|
|
|
|
|
|
-/* History:
|
|
|
- * 0.3a - implemented pools of write URBs
|
|
|
- * 0.3 - alpha version for public testing
|
|
|
- * 0.2 - TIOCMGET works, so autopilot(1) can be used!
|
|
|
- * 0.1 - can be used to do pilot-xfer -p /dev/ttyUSB0 -l
|
|
|
- *
|
|
|
- * The driver skeleton is mainly based on mct_u232.c and various other
|
|
|
- * pieces of code shamelessly copied from the drivers/usb/serial/ directory.
|
|
|
- */
|
|
|
-
|
|
|
-
|
|
|
#include <linux/kernel.h>
|
|
|
#include <linux/errno.h>
|
|
|
#include <linux/init.h>
|
|
@@ -64,8 +54,8 @@ static int debug;
|
|
|
/*
|
|
|
* Version Information
|
|
|
*/
|
|
|
-#define DRIVER_VERSION "v0.3a"
|
|
|
-#define DRIVER_AUTHOR "Utz-Uwe Haus <haus@uuhaus.de>"
|
|
|
+#define DRIVER_VERSION "v0.4"
|
|
|
+#define DRIVER_AUTHOR "Utz-Uwe Haus <haus@uuhaus.de>, Johan Hovold <jhovold@gmail.com>"
|
|
|
#define DRIVER_DESC "KLSI KL5KUSB105 chipset USB->Serial Converter driver"
|
|
|
|
|
|
|
|
@@ -73,23 +63,17 @@ static int debug;
|
|
|
* Function prototypes
|
|
|
*/
|
|
|
static int klsi_105_startup(struct usb_serial *serial);
|
|
|
-static void klsi_105_disconnect(struct usb_serial *serial);
|
|
|
static void klsi_105_release(struct usb_serial *serial);
|
|
|
static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port);
|
|
|
static void klsi_105_close(struct usb_serial_port *port);
|
|
|
-static int klsi_105_write(struct tty_struct *tty,
|
|
|
- struct usb_serial_port *port, const unsigned char *buf, int count);
|
|
|
-static void klsi_105_write_bulk_callback(struct urb *urb);
|
|
|
-static int klsi_105_chars_in_buffer(struct tty_struct *tty);
|
|
|
-static int klsi_105_write_room(struct tty_struct *tty);
|
|
|
-static void klsi_105_read_bulk_callback(struct urb *urb);
|
|
|
static void klsi_105_set_termios(struct tty_struct *tty,
|
|
|
struct usb_serial_port *port, struct ktermios *old);
|
|
|
-static void klsi_105_throttle(struct tty_struct *tty);
|
|
|
-static void klsi_105_unthrottle(struct tty_struct *tty);
|
|
|
static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file);
|
|
|
static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file,
|
|
|
unsigned int set, unsigned int clear);
|
|
|
+static void klsi_105_process_read_urb(struct urb *urb);
|
|
|
+static int klsi_105_prepare_write_buffer(struct usb_serial_port *port,
|
|
|
+ void *dest, size_t size);
|
|
|
|
|
|
/*
|
|
|
* All of the device info needed for the KLSI converters.
|
|
@@ -119,22 +103,19 @@ static struct usb_serial_driver kl5kusb105d_device = {
|
|
|
.usb_driver = &kl5kusb105d_driver,
|
|
|
.id_table = id_table,
|
|
|
.num_ports = 1,
|
|
|
+ .bulk_out_size = 64,
|
|
|
.open = klsi_105_open,
|
|
|
.close = klsi_105_close,
|
|
|
- .write = klsi_105_write,
|
|
|
- .write_bulk_callback = klsi_105_write_bulk_callback,
|
|
|
- .chars_in_buffer = klsi_105_chars_in_buffer,
|
|
|
- .write_room = klsi_105_write_room,
|
|
|
- .read_bulk_callback = klsi_105_read_bulk_callback,
|
|
|
.set_termios = klsi_105_set_termios,
|
|
|
/*.break_ctl = klsi_105_break_ctl,*/
|
|
|
.tiocmget = klsi_105_tiocmget,
|
|
|
.tiocmset = klsi_105_tiocmset,
|
|
|
.attach = klsi_105_startup,
|
|
|
- .disconnect = klsi_105_disconnect,
|
|
|
.release = klsi_105_release,
|
|
|
- .throttle = klsi_105_throttle,
|
|
|
- .unthrottle = klsi_105_unthrottle,
|
|
|
+ .throttle = usb_serial_generic_throttle,
|
|
|
+ .unthrottle = usb_serial_generic_unthrottle,
|
|
|
+ .process_read_urb = klsi_105_process_read_urb,
|
|
|
+ .prepare_write_buffer = klsi_105_prepare_write_buffer,
|
|
|
};
|
|
|
|
|
|
struct klsi_105_port_settings {
|
|
@@ -145,18 +126,11 @@ struct klsi_105_port_settings {
|
|
|
__u8 unknown2;
|
|
|
} __attribute__ ((packed));
|
|
|
|
|
|
-/* we implement a pool of NUM_URBS urbs per usb_serial */
|
|
|
-#define NUM_URBS 1
|
|
|
-#define URB_TRANSFER_BUFFER_SIZE 64
|
|
|
struct klsi_105_private {
|
|
|
struct klsi_105_port_settings cfg;
|
|
|
struct ktermios termios;
|
|
|
unsigned long line_state; /* modem line settings */
|
|
|
- /* write pool */
|
|
|
- struct urb *write_urb_pool[NUM_URBS];
|
|
|
spinlock_t lock;
|
|
|
- unsigned long bytes_in;
|
|
|
- unsigned long bytes_out;
|
|
|
};
|
|
|
|
|
|
|
|
@@ -259,7 +233,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
|
|
|
static int klsi_105_startup(struct usb_serial *serial)
|
|
|
{
|
|
|
struct klsi_105_private *priv;
|
|
|
- int i, j;
|
|
|
+ int i;
|
|
|
|
|
|
/* check if we support the product id (see keyspan.c)
|
|
|
* FIXME
|
|
@@ -283,29 +257,9 @@ static int klsi_105_startup(struct usb_serial *serial)
|
|
|
|
|
|
priv->line_state = 0;
|
|
|
|
|
|
- priv->bytes_in = 0;
|
|
|
- priv->bytes_out = 0;
|
|
|
usb_set_serial_port_data(serial->port[i], priv);
|
|
|
|
|
|
spin_lock_init(&priv->lock);
|
|
|
- for (j = 0; j < NUM_URBS; j++) {
|
|
|
- struct urb *urb = usb_alloc_urb(0, GFP_KERNEL);
|
|
|
-
|
|
|
- priv->write_urb_pool[j] = urb;
|
|
|
- if (urb == NULL) {
|
|
|
- dev_err(&serial->dev->dev, "No more urbs???\n");
|
|
|
- goto err_cleanup;
|
|
|
- }
|
|
|
-
|
|
|
- urb->transfer_buffer =
|
|
|
- kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
|
|
|
- if (!urb->transfer_buffer) {
|
|
|
- dev_err(&serial->dev->dev,
|
|
|
- "%s - out of memory for urb buffers.\n",
|
|
|
- __func__);
|
|
|
- goto err_cleanup;
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
/* priv->termios is left uninitalized until port opening */
|
|
|
init_waitqueue_head(&serial->port[i]->write_wait);
|
|
@@ -316,56 +270,20 @@ static int klsi_105_startup(struct usb_serial *serial)
|
|
|
err_cleanup:
|
|
|
for (; i >= 0; i--) {
|
|
|
priv = usb_get_serial_port_data(serial->port[i]);
|
|
|
- for (j = 0; j < NUM_URBS; j++) {
|
|
|
- if (priv->write_urb_pool[j]) {
|
|
|
- kfree(priv->write_urb_pool[j]->transfer_buffer);
|
|
|
- usb_free_urb(priv->write_urb_pool[j]);
|
|
|
- }
|
|
|
- }
|
|
|
kfree(priv);
|
|
|
usb_set_serial_port_data(serial->port[i], NULL);
|
|
|
}
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
-static void klsi_105_disconnect(struct usb_serial *serial)
|
|
|
-{
|
|
|
- int i;
|
|
|
-
|
|
|
- dbg("%s", __func__);
|
|
|
-
|
|
|
- /* stop reads and writes on all ports */
|
|
|
- for (i = 0; i < serial->num_ports; ++i) {
|
|
|
- struct klsi_105_private *priv =
|
|
|
- usb_get_serial_port_data(serial->port[i]);
|
|
|
-
|
|
|
- if (priv) {
|
|
|
- /* kill our write urb pool */
|
|
|
- int j;
|
|
|
- struct urb **write_urbs = priv->write_urb_pool;
|
|
|
-
|
|
|
- for (j = 0; j < NUM_URBS; j++) {
|
|
|
- if (write_urbs[j]) {
|
|
|
- usb_kill_urb(write_urbs[j]);
|
|
|
- usb_free_urb(write_urbs[j]);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
static void klsi_105_release(struct usb_serial *serial)
|
|
|
{
|
|
|
int i;
|
|
|
|
|
|
dbg("%s", __func__);
|
|
|
|
|
|
- for (i = 0; i < serial->num_ports; ++i) {
|
|
|
- struct klsi_105_private *priv =
|
|
|
- usb_get_serial_port_data(serial->port[i]);
|
|
|
-
|
|
|
- kfree(priv);
|
|
|
- }
|
|
|
+ for (i = 0; i < serial->num_ports; ++i)
|
|
|
+ kfree(usb_get_serial_port_data(serial->port[i]));
|
|
|
}
|
|
|
|
|
|
static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|
@@ -416,18 +334,8 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|
|
spin_unlock_irqrestore(&priv->lock, flags);
|
|
|
|
|
|
/* READ_ON and urb submission */
|
|
|
- usb_fill_bulk_urb(port->read_urb, port->serial->dev,
|
|
|
- usb_rcvbulkpipe(port->serial->dev,
|
|
|
- port->bulk_in_endpointAddress),
|
|
|
- port->read_urb->transfer_buffer,
|
|
|
- port->read_urb->transfer_buffer_length,
|
|
|
- klsi_105_read_bulk_callback,
|
|
|
- port);
|
|
|
-
|
|
|
- rc = usb_submit_urb(port->read_urb, GFP_KERNEL);
|
|
|
+ rc = usb_serial_generic_open(tty, port);
|
|
|
if (rc) {
|
|
|
- dev_err(&port->dev, "%s - failed submitting read urb, "
|
|
|
- "error %d\n", __func__, rc);
|
|
|
retval = rc;
|
|
|
goto exit;
|
|
|
}
|
|
@@ -464,7 +372,6 @@ exit:
|
|
|
|
|
|
static void klsi_105_close(struct usb_serial_port *port)
|
|
|
{
|
|
|
- struct klsi_105_private *priv = usb_get_serial_port_data(port);
|
|
|
int rc;
|
|
|
|
|
|
dbg("%s port %d", __func__, port->number);
|
|
@@ -487,232 +394,61 @@ static void klsi_105_close(struct usb_serial_port *port)
|
|
|
mutex_unlock(&port->serial->disc_mutex);
|
|
|
|
|
|
/* shutdown our bulk reads and writes */
|
|
|
- usb_kill_urb(port->write_urb);
|
|
|
- usb_kill_urb(port->read_urb);
|
|
|
- /* unlink our write pool */
|
|
|
- /* FIXME */
|
|
|
+ usb_serial_generic_close(port);
|
|
|
+
|
|
|
/* wgg - do I need this? I think so. */
|
|
|
usb_kill_urb(port->interrupt_in_urb);
|
|
|
- dev_info(&port->serial->dev->dev,
|
|
|
- "port stats: %ld bytes in, %ld bytes out\n",
|
|
|
- priv->bytes_in, priv->bytes_out);
|
|
|
}
|
|
|
|
|
|
/* We need to write a complete 64-byte data block and encode the
|
|
|
* number actually sent in the first double-byte, LSB-order. That
|
|
|
* leaves at most 62 bytes of payload.
|
|
|
*/
|
|
|
-#define KLSI_105_DATA_OFFSET 2 /* in the bulk urb data block */
|
|
|
-
|
|
|
-static int klsi_105_write(struct tty_struct *tty,
|
|
|
- struct usb_serial_port *port, const unsigned char *buf, int count)
|
|
|
-{
|
|
|
- struct klsi_105_private *priv = usb_get_serial_port_data(port);
|
|
|
- int result, size;
|
|
|
- int bytes_sent = 0;
|
|
|
-
|
|
|
- dbg("%s - port %d", __func__, port->number);
|
|
|
-
|
|
|
- while (count > 0) {
|
|
|
- /* try to find a free urb (write 0 bytes if none) */
|
|
|
- struct urb *urb = NULL;
|
|
|
- unsigned long flags;
|
|
|
- int i;
|
|
|
- /* since the pool is per-port we might not need
|
|
|
- the spin lock !? */
|
|
|
- spin_lock_irqsave(&priv->lock, flags);
|
|
|
- for (i = 0; i < NUM_URBS; i++) {
|
|
|
- if (priv->write_urb_pool[i]->status != -EINPROGRESS) {
|
|
|
- urb = priv->write_urb_pool[i];
|
|
|
- dbg("%s - using pool URB %d", __func__, i);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- spin_unlock_irqrestore(&priv->lock, flags);
|
|
|
-
|
|
|
- if (urb == NULL) {
|
|
|
- dbg("%s - no more free urbs", __func__);
|
|
|
- goto exit;
|
|
|
- }
|
|
|
-
|
|
|
- if (urb->transfer_buffer == NULL) {
|
|
|
- urb->transfer_buffer =
|
|
|
- kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC);
|
|
|
- if (urb->transfer_buffer == NULL) {
|
|
|
- dev_err(&port->dev,
|
|
|
- "%s - no more kernel memory...\n",
|
|
|
- __func__);
|
|
|
- goto exit;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- size = min(count, port->bulk_out_size - KLSI_105_DATA_OFFSET);
|
|
|
- size = min(size, URB_TRANSFER_BUFFER_SIZE -
|
|
|
- KLSI_105_DATA_OFFSET);
|
|
|
-
|
|
|
- memcpy(urb->transfer_buffer + KLSI_105_DATA_OFFSET, buf, size);
|
|
|
-
|
|
|
- /* write payload size into transfer buffer */
|
|
|
- ((__u8 *)urb->transfer_buffer)[0] = (__u8) (size & 0xFF);
|
|
|
- ((__u8 *)urb->transfer_buffer)[1] = (__u8) ((size & 0xFF00)>>8);
|
|
|
-
|
|
|
- /* set up our urb */
|
|
|
- usb_fill_bulk_urb(urb, port->serial->dev,
|
|
|
- usb_sndbulkpipe(port->serial->dev,
|
|
|
- port->bulk_out_endpointAddress),
|
|
|
- urb->transfer_buffer,
|
|
|
- URB_TRANSFER_BUFFER_SIZE,
|
|
|
- klsi_105_write_bulk_callback,
|
|
|
- port);
|
|
|
-
|
|
|
- /* send the data out the bulk port */
|
|
|
- result = usb_submit_urb(urb, GFP_ATOMIC);
|
|
|
- if (result) {
|
|
|
- dev_err(&port->dev,
|
|
|
- "%s - failed submitting write urb, error %d\n",
|
|
|
- __func__, result);
|
|
|
- goto exit;
|
|
|
- }
|
|
|
- buf += size;
|
|
|
- bytes_sent += size;
|
|
|
- count -= size;
|
|
|
- }
|
|
|
-exit:
|
|
|
- /* lockless, but it's for debug info only... */
|
|
|
- priv->bytes_out += bytes_sent;
|
|
|
-
|
|
|
- return bytes_sent; /* that's how much we wrote */
|
|
|
-}
|
|
|
-
|
|
|
-static void klsi_105_write_bulk_callback(struct urb *urb)
|
|
|
+#define KLSI_HDR_LEN 2
|
|
|
+static int klsi_105_prepare_write_buffer(struct usb_serial_port *port,
|
|
|
+ void *dest, size_t size)
|
|
|
{
|
|
|
- struct usb_serial_port *port = urb->context;
|
|
|
- int status = urb->status;
|
|
|
-
|
|
|
- dbg("%s - port %d", __func__, port->number);
|
|
|
+ unsigned char *buf = dest;
|
|
|
+ int count;
|
|
|
|
|
|
- if (status) {
|
|
|
- dbg("%s - nonzero write bulk status received: %d", __func__,
|
|
|
- status);
|
|
|
- return;
|
|
|
- }
|
|
|
+ count = kfifo_out_locked(&port->write_fifo, buf + KLSI_HDR_LEN, size,
|
|
|
+ &port->lock);
|
|
|
+ put_unaligned_le16(count, buf);
|
|
|
|
|
|
- usb_serial_port_softint(port);
|
|
|
+ return count + KLSI_HDR_LEN;
|
|
|
}
|
|
|
|
|
|
-/* return number of characters currently in the writing process */
|
|
|
-static int klsi_105_chars_in_buffer(struct tty_struct *tty)
|
|
|
-{
|
|
|
- struct usb_serial_port *port = tty->driver_data;
|
|
|
- int chars = 0;
|
|
|
- int i;
|
|
|
- unsigned long flags;
|
|
|
- struct klsi_105_private *priv = usb_get_serial_port_data(port);
|
|
|
-
|
|
|
- spin_lock_irqsave(&priv->lock, flags);
|
|
|
-
|
|
|
- for (i = 0; i < NUM_URBS; ++i) {
|
|
|
- if (priv->write_urb_pool[i]->status == -EINPROGRESS)
|
|
|
- chars += URB_TRANSFER_BUFFER_SIZE;
|
|
|
- }
|
|
|
-
|
|
|
- spin_unlock_irqrestore(&priv->lock, flags);
|
|
|
-
|
|
|
- dbg("%s - returns %d", __func__, chars);
|
|
|
- return chars;
|
|
|
-}
|
|
|
-
|
|
|
-static int klsi_105_write_room(struct tty_struct *tty)
|
|
|
-{
|
|
|
- struct usb_serial_port *port = tty->driver_data;
|
|
|
- unsigned long flags;
|
|
|
- int i;
|
|
|
- int room = 0;
|
|
|
- struct klsi_105_private *priv = usb_get_serial_port_data(port);
|
|
|
-
|
|
|
- spin_lock_irqsave(&priv->lock, flags);
|
|
|
- for (i = 0; i < NUM_URBS; ++i) {
|
|
|
- if (priv->write_urb_pool[i]->status != -EINPROGRESS)
|
|
|
- room += URB_TRANSFER_BUFFER_SIZE;
|
|
|
- }
|
|
|
-
|
|
|
- spin_unlock_irqrestore(&priv->lock, flags);
|
|
|
-
|
|
|
- dbg("%s - returns %d", __func__, room);
|
|
|
- return room;
|
|
|
-}
|
|
|
-
|
|
|
-static void klsi_105_read_bulk_callback(struct urb *urb)
|
|
|
+/* The data received is preceded by a length double-byte in LSB-first order.
|
|
|
+ */
|
|
|
+static void klsi_105_process_read_urb(struct urb *urb)
|
|
|
{
|
|
|
struct usb_serial_port *port = urb->context;
|
|
|
- struct klsi_105_private *priv = usb_get_serial_port_data(port);
|
|
|
- struct tty_struct *tty;
|
|
|
unsigned char *data = urb->transfer_buffer;
|
|
|
- int rc;
|
|
|
- int status = urb->status;
|
|
|
+ struct tty_struct *tty;
|
|
|
+ unsigned len;
|
|
|
|
|
|
- dbg("%s - port %d", __func__, port->number);
|
|
|
+ /* empty urbs seem to happen, we ignore them */
|
|
|
+ if (!urb->actual_length)
|
|
|
+ return;
|
|
|
|
|
|
- /* The urb might have been killed. */
|
|
|
- if (status) {
|
|
|
- dbg("%s - nonzero read bulk status received: %d", __func__,
|
|
|
- status);
|
|
|
+ if (urb->actual_length <= KLSI_HDR_LEN) {
|
|
|
+ dbg("%s - malformed packet", __func__);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- /* The data received is again preceded by a length double-byte in LSB-
|
|
|
- * first order (see klsi_105_write() )
|
|
|
- */
|
|
|
- if (urb->actual_length == 0) {
|
|
|
- /* empty urbs seem to happen, we ignore them */
|
|
|
- /* dbg("%s - emtpy URB", __func__); */
|
|
|
- ;
|
|
|
- } else if (urb->actual_length <= 2) {
|
|
|
- dbg("%s - size %d URB not understood", __func__,
|
|
|
- urb->actual_length);
|
|
|
- usb_serial_debug_data(debug, &port->dev, __func__,
|
|
|
- urb->actual_length, data);
|
|
|
- } else {
|
|
|
- int bytes_sent = ((__u8 *) data)[0] +
|
|
|
- ((unsigned int) ((__u8 *) data)[1] << 8);
|
|
|
- tty = tty_port_tty_get(&port->port);
|
|
|
- /* we should immediately resubmit the URB, before attempting
|
|
|
- * to pass the data on to the tty layer. But that needs locking
|
|
|
- * against re-entry an then mixed-up data because of
|
|
|
- * intermixed tty_flip_buffer_push()s
|
|
|
- * FIXME
|
|
|
- */
|
|
|
- usb_serial_debug_data(debug, &port->dev, __func__,
|
|
|
- urb->actual_length, data);
|
|
|
-
|
|
|
- if (bytes_sent + 2 > urb->actual_length) {
|
|
|
- dbg("%s - trying to read more data than available"
|
|
|
- " (%d vs. %d)", __func__,
|
|
|
- bytes_sent+2, urb->actual_length);
|
|
|
- /* cap at implied limit */
|
|
|
- bytes_sent = urb->actual_length - 2;
|
|
|
- }
|
|
|
-
|
|
|
- tty_insert_flip_string(tty, data + 2, bytes_sent);
|
|
|
- tty_flip_buffer_push(tty);
|
|
|
- tty_kref_put(tty);
|
|
|
+ tty = tty_port_tty_get(&port->port);
|
|
|
+ if (!tty)
|
|
|
+ return;
|
|
|
|
|
|
- /* again lockless, but debug info only */
|
|
|
- priv->bytes_in += bytes_sent;
|
|
|
+ len = get_unaligned_le16(data);
|
|
|
+ if (len > urb->actual_length - KLSI_HDR_LEN) {
|
|
|
+ dbg("%s - packet length mismatch", __func__);
|
|
|
+ len = urb->actual_length - KLSI_HDR_LEN;
|
|
|
}
|
|
|
- /* Continue trying to always read */
|
|
|
- usb_fill_bulk_urb(port->read_urb, port->serial->dev,
|
|
|
- usb_rcvbulkpipe(port->serial->dev,
|
|
|
- port->bulk_in_endpointAddress),
|
|
|
- port->read_urb->transfer_buffer,
|
|
|
- port->read_urb->transfer_buffer_length,
|
|
|
- klsi_105_read_bulk_callback,
|
|
|
- port);
|
|
|
- rc = usb_submit_urb(port->read_urb, GFP_ATOMIC);
|
|
|
- if (rc)
|
|
|
- dev_err(&port->dev,
|
|
|
- "%s - failed resubmitting read urb, error %d\n",
|
|
|
- __func__, rc);
|
|
|
+
|
|
|
+ tty_insert_flip_string(tty, data + KLSI_HDR_LEN, len);
|
|
|
+ tty_flip_buffer_push(tty);
|
|
|
+ tty_kref_put(tty);
|
|
|
}
|
|
|
|
|
|
static void klsi_105_set_termios(struct tty_struct *tty,
|
|
@@ -954,28 +690,6 @@ static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file,
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-static void klsi_105_throttle(struct tty_struct *tty)
|
|
|
-{
|
|
|
- struct usb_serial_port *port = tty->driver_data;
|
|
|
- dbg("%s - port %d", __func__, port->number);
|
|
|
- usb_kill_urb(port->read_urb);
|
|
|
-}
|
|
|
-
|
|
|
-static void klsi_105_unthrottle(struct tty_struct *tty)
|
|
|
-{
|
|
|
- struct usb_serial_port *port = tty->driver_data;
|
|
|
- int result;
|
|
|
-
|
|
|
- dbg("%s - port %d", __func__, port->number);
|
|
|
-
|
|
|
- port->read_urb->dev = port->serial->dev;
|
|
|
- result = usb_submit_urb(port->read_urb, GFP_KERNEL);
|
|
|
- if (result)
|
|
|
- dev_err(&port->dev,
|
|
|
- "%s - failed submitting read urb, error %d\n",
|
|
|
- __func__, result);
|
|
|
-}
|
|
|
-
|
|
|
|
|
|
static int __init klsi_105_init(void)
|
|
|
{
|