aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/serial/kl5kusb105.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/kl5kusb105.c')
-rw-r--r--drivers/usb/serial/kl5kusb105.c241
1 files changed, 74 insertions, 167 deletions
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index e8a65ce45a2..d7440b7557a 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -37,7 +37,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
-#include <linux/init.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
@@ -49,12 +48,6 @@
#include <linux/usb/serial.h>
#include "kl5kusb105.h"
-static int debug;
-
-/*
- * Version Information
- */
-#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"
@@ -62,14 +55,14 @@ static int debug;
/*
* Function prototypes
*/
-static int klsi_105_startup(struct usb_serial *serial);
-static void klsi_105_release(struct usb_serial *serial);
+static int klsi_105_port_probe(struct usb_serial_port *port);
+static int klsi_105_port_remove(struct usb_serial_port *port);
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 void klsi_105_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old);
-static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file);
-static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file,
+static int klsi_105_tiocmget(struct tty_struct *tty);
+static int klsi_105_tiocmset(struct tty_struct *tty,
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,
@@ -86,21 +79,12 @@ static const struct usb_device_id id_table[] = {
MODULE_DEVICE_TABLE(usb, id_table);
-static struct usb_driver kl5kusb105d_driver = {
- .name = "kl5kusb105d",
- .probe = usb_serial_probe,
- .disconnect = usb_serial_disconnect,
- .id_table = id_table,
- .no_dynamic_id = 1,
-};
-
static struct usb_serial_driver kl5kusb105d_device = {
.driver = {
.owner = THIS_MODULE,
.name = "kl5kusb105d",
},
.description = "KL5KUSB105D / PalmConnect",
- .usb_driver = &kl5kusb105d_driver,
.id_table = id_table,
.num_ports = 1,
.bulk_out_size = 64,
@@ -110,14 +94,18 @@ static struct usb_serial_driver kl5kusb105d_device = {
/*.break_ctl = klsi_105_break_ctl,*/
.tiocmget = klsi_105_tiocmget,
.tiocmset = klsi_105_tiocmset,
- .attach = klsi_105_startup,
- .release = klsi_105_release,
+ .port_probe = klsi_105_port_probe,
+ .port_remove = klsi_105_port_remove,
.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,
};
+static struct usb_serial_driver * const serial_drivers[] = {
+ &kl5kusb105d_device, NULL
+};
+
struct klsi_105_port_settings {
__u8 pktlen; /* always 5, it seems */
__u8 baudrate;
@@ -193,11 +181,9 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
dev_info(&port->serial->dev->dev, "sending SIO Poll request\n");
status_buf = kmalloc(KLSI_STATUSBUF_LEN, GFP_KERNEL);
- if (!status_buf) {
- dev_err(&port->dev, "%s - out of memory for status buffer.\n",
- __func__);
+ if (!status_buf)
return -ENOMEM;
- }
+
status_buf[0] = 0xff;
status_buf[1] = 0xff;
rc = usb_control_msg(port->serial->dev,
@@ -215,7 +201,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
else {
status = get_unaligned_le16(status_buf);
- dev_info(&port->serial->dev->dev, "read status %x %x",
+ dev_info(&port->serial->dev->dev, "read status %x %x\n",
status_buf[0], status_buf[1]);
*line_state_p = klsi_105_status2linestate(status);
@@ -230,60 +216,40 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
* Driver's tty interface functions
*/
-static int klsi_105_startup(struct usb_serial *serial)
+static int klsi_105_port_probe(struct usb_serial_port *port)
{
struct klsi_105_private *priv;
- int i;
- /* check if we support the product id (see keyspan.c)
- * FIXME
- */
+ priv = kmalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
- /* allocate the private data structure */
- for (i = 0; i < serial->num_ports; i++) {
- priv = kmalloc(sizeof(struct klsi_105_private),
- GFP_KERNEL);
- if (!priv) {
- dbg("%skmalloc for klsi_105_private failed.", __func__);
- i--;
- goto err_cleanup;
- }
- /* set initial values for control structures */
- priv->cfg.pktlen = 5;
- priv->cfg.baudrate = kl5kusb105a_sio_b9600;
- priv->cfg.databits = kl5kusb105a_dtb_8;
- priv->cfg.unknown1 = 0;
- priv->cfg.unknown2 = 1;
+ /* set initial values for control structures */
+ priv->cfg.pktlen = 5;
+ priv->cfg.baudrate = kl5kusb105a_sio_b9600;
+ priv->cfg.databits = kl5kusb105a_dtb_8;
+ priv->cfg.unknown1 = 0;
+ priv->cfg.unknown2 = 1;
- priv->line_state = 0;
+ priv->line_state = 0;
- usb_set_serial_port_data(serial->port[i], priv);
+ spin_lock_init(&priv->lock);
- spin_lock_init(&priv->lock);
+ /* priv->termios is left uninitialized until port opening */
- /* priv->termios is left uninitialized until port opening */
- init_waitqueue_head(&serial->port[i]->write_wait);
- }
+ usb_set_serial_port_data(port, priv);
return 0;
-
-err_cleanup:
- for (; i >= 0; i--) {
- priv = usb_get_serial_port_data(serial->port[i]);
- kfree(priv);
- usb_set_serial_port_data(serial->port[i], NULL);
- }
- return -ENOMEM;
}
-static void klsi_105_release(struct usb_serial *serial)
+static int klsi_105_port_remove(struct usb_serial_port *port)
{
- int i;
+ struct klsi_105_private *priv;
- dbg("%s", __func__);
+ priv = usb_get_serial_port_data(port);
+ kfree(priv);
- for (i = 0; i < serial->num_ports; ++i)
- kfree(usb_get_serial_port_data(serial->port[i]));
+ return 0;
}
static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
@@ -296,8 +262,6 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
struct klsi_105_port_settings *cfg;
unsigned long flags;
- dbg("%s port %d", __func__, port->number);
-
/* Do a defined restart:
* Set up sane default baud rate and send the 'READ_ON'
* vendor command.
@@ -306,11 +270,9 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
* priv->line_state.
*/
cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
- if (!cfg) {
- dev_err(&port->dev, "%s - out of memory for config buffer.\n",
- __func__);
+ if (!cfg)
return -ENOMEM;
- }
+
cfg->pktlen = 5;
cfg->baudrate = kl5kusb105a_sio_b9600;
cfg->databits = kl5kusb105a_dtb_8;
@@ -320,12 +282,12 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
/* set up termios structure */
spin_lock_irqsave(&priv->lock, flags);
- priv->termios.c_iflag = tty->termios->c_iflag;
- priv->termios.c_oflag = tty->termios->c_oflag;
- priv->termios.c_cflag = tty->termios->c_cflag;
- priv->termios.c_lflag = tty->termios->c_lflag;
+ priv->termios.c_iflag = tty->termios.c_iflag;
+ priv->termios.c_oflag = tty->termios.c_oflag;
+ priv->termios.c_cflag = tty->termios.c_cflag;
+ priv->termios.c_lflag = tty->termios.c_lflag;
for (i = 0; i < NCCS; i++)
- priv->termios.c_cc[i] = tty->termios->c_cc[i];
+ priv->termios.c_cc[i] = tty->termios.c_cc[i];
priv->cfg.pktlen = cfg->pktlen;
priv->cfg.baudrate = cfg->baudrate;
priv->cfg.databits = cfg->databits;
@@ -353,14 +315,14 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
dev_err(&port->dev, "Enabling read failed (error = %d)\n", rc);
retval = rc;
} else
- dbg("%s - enabled reading", __func__);
+ dev_dbg(&port->dev, "%s - enabled reading\n", __func__);
rc = klsi_105_get_line_state(port, &line_state);
if (rc >= 0) {
spin_lock_irqsave(&priv->lock, flags);
priv->line_state = line_state;
spin_unlock_irqrestore(&priv->lock, flags);
- dbg("%s - read line state 0x%lx", __func__, line_state);
+ dev_dbg(&port->dev, "%s - read line state 0x%lx\n", __func__, line_state);
retval = 0;
} else
retval = rc;
@@ -374,30 +336,20 @@ static void klsi_105_close(struct usb_serial_port *port)
{
int rc;
- dbg("%s port %d", __func__, port->number);
-
- mutex_lock(&port->serial->disc_mutex);
- if (!port->serial->disconnected) {
- /* send READ_OFF */
- rc = usb_control_msg(port->serial->dev,
- usb_sndctrlpipe(port->serial->dev, 0),
- KL5KUSB105A_SIO_CONFIGURE,
- USB_TYPE_VENDOR | USB_DIR_OUT,
- KL5KUSB105A_SIO_CONFIGURE_READ_OFF,
- 0, /* index */
- NULL, 0,
- KLSI_TIMEOUT);
- if (rc < 0)
- dev_err(&port->dev,
- "Disabling read failed (error = %d)\n", rc);
- }
- mutex_unlock(&port->serial->disc_mutex);
+ /* send READ_OFF */
+ rc = usb_control_msg(port->serial->dev,
+ usb_sndctrlpipe(port->serial->dev, 0),
+ KL5KUSB105A_SIO_CONFIGURE,
+ USB_TYPE_VENDOR | USB_DIR_OUT,
+ KL5KUSB105A_SIO_CONFIGURE_READ_OFF,
+ 0, /* index */
+ NULL, 0,
+ KLSI_TIMEOUT);
+ if (rc < 0)
+ dev_err(&port->dev, "failed to disable read: %d\n", rc);
/* shutdown our bulk reads and writes */
usb_serial_generic_close(port);
-
- /* wgg - do I need this? I think so. */
- usb_kill_urb(port->interrupt_in_urb);
}
/* We need to write a complete 64-byte data block and encode the
@@ -424,7 +376,6 @@ static void klsi_105_process_read_urb(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
unsigned char *data = urb->transfer_buffer;
- struct tty_struct *tty;
unsigned len;
/* empty urbs seem to happen, we ignore them */
@@ -432,23 +383,18 @@ static void klsi_105_process_read_urb(struct urb *urb)
return;
if (urb->actual_length <= KLSI_HDR_LEN) {
- dbg("%s - malformed packet", __func__);
+ dev_dbg(&port->dev, "%s - malformed packet\n", __func__);
return;
}
- tty = tty_port_tty_get(&port->port);
- if (!tty)
- return;
-
len = get_unaligned_le16(data);
if (len > urb->actual_length - KLSI_HDR_LEN) {
- dbg("%s - packet length mismatch", __func__);
+ dev_dbg(&port->dev, "%s - packet length mismatch\n", __func__);
len = urb->actual_length - KLSI_HDR_LEN;
}
- tty_insert_flip_string(tty, data + KLSI_HDR_LEN, len);
- tty_flip_buffer_push(tty);
- tty_kref_put(tty);
+ tty_insert_flip_string(&port->port, data + KLSI_HDR_LEN, len);
+ tty_flip_buffer_push(&port->port);
}
static void klsi_105_set_termios(struct tty_struct *tty,
@@ -456,20 +402,18 @@ static void klsi_105_set_termios(struct tty_struct *tty,
struct ktermios *old_termios)
{
struct klsi_105_private *priv = usb_get_serial_port_data(port);
- unsigned int iflag = tty->termios->c_iflag;
+ struct device *dev = &port->dev;
+ unsigned int iflag = tty->termios.c_iflag;
unsigned int old_iflag = old_termios->c_iflag;
- unsigned int cflag = tty->termios->c_cflag;
+ unsigned int cflag = tty->termios.c_cflag;
unsigned int old_cflag = old_termios->c_cflag;
struct klsi_105_port_settings *cfg;
unsigned long flags;
speed_t baud;
cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
- if (!cfg) {
- dev_err(&port->dev, "%s - out of memory for config buffer.\n",
- __func__);
+ if (!cfg)
return;
- }
/* lock while we are modifying the settings */
spin_lock_irqsave(&priv->lock, flags);
@@ -482,7 +426,7 @@ static void klsi_105_set_termios(struct tty_struct *tty,
if ((cflag & CBAUD) != (old_cflag & CBAUD)) {
/* reassert DTR and (maybe) RTS on transition from B0 */
if ((old_cflag & CBAUD) == B0) {
- dbg("%s: baud was B0", __func__);
+ dev_dbg(dev, "%s: baud was B0\n", __func__);
#if 0
priv->control_state |= TIOCM_DTR;
/* don't set RTS if using hardware flow control */
@@ -520,14 +464,13 @@ static void klsi_105_set_termios(struct tty_struct *tty,
priv->cfg.baudrate = kl5kusb105a_sio_b115200;
break;
default:
- dbg("KLSI USB->Serial converter:"
- " unsupported baudrate request, using default of 9600");
- priv->cfg.baudrate = kl5kusb105a_sio_b9600;
+ dev_dbg(dev, "unsupported baudrate, using 9600\n");
+ priv->cfg.baudrate = kl5kusb105a_sio_b9600;
baud = 9600;
break;
}
if ((cflag & CBAUD) == B0) {
- dbg("%s: baud is B0", __func__);
+ dev_dbg(dev, "%s: baud is B0\n", __func__);
/* Drop RTS and DTR */
/* maybe this should be simulated by sending read
* disable and read enable messages?
@@ -544,11 +487,11 @@ static void klsi_105_set_termios(struct tty_struct *tty,
/* set the number of data bits */
switch (cflag & CSIZE) {
case CS5:
- dbg("%s - 5 bits/byte not supported", __func__);
+ dev_dbg(dev, "%s - 5 bits/byte not supported\n", __func__);
spin_unlock_irqrestore(&priv->lock, flags);
goto err;
case CS6:
- dbg("%s - 6 bits/byte not supported", __func__);
+ dev_dbg(dev, "%s - 6 bits/byte not supported\n", __func__);
spin_unlock_irqrestore(&priv->lock, flags);
goto err;
case CS7:
@@ -558,8 +501,7 @@ static void klsi_105_set_termios(struct tty_struct *tty,
priv->cfg.databits = kl5kusb105a_dtb_8;
break;
default:
- dev_err(&port->dev,
- "CSIZE was not CS5-CS8, using default of 8\n");
+ dev_err(dev, "CSIZE was not CS5-CS8, using default of 8\n");
priv->cfg.databits = kl5kusb105a_dtb_8;
break;
}
@@ -571,7 +513,7 @@ static void klsi_105_set_termios(struct tty_struct *tty,
if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))
|| (cflag & CSTOPB) != (old_cflag & CSTOPB)) {
/* Not currently supported */
- tty->termios->c_cflag &= ~(PARENB|PARODD|CSTOPB);
+ tty->termios.c_cflag &= ~(PARENB|PARODD|CSTOPB);
#if 0
priv->last_lcr = 0;
@@ -598,7 +540,7 @@ static void klsi_105_set_termios(struct tty_struct *tty,
|| (iflag & IXON) != (old_iflag & IXON)
|| (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
/* Not currently supported */
- tty->termios->c_cflag &= ~CRTSCTS;
+ tty->termios.c_cflag &= ~CRTSCTS;
/* Drop DTR/RTS if no flow control otherwise assert */
#if 0
if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS))
@@ -627,7 +569,7 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
(struct mct_u232_private *)port->private;
unsigned char lcr = priv->last_lcr;
- dbg("%sstate=%d", __func__, break_state);
+ dev_dbg(&port->dev, "%s - state=%d\n", __func__, break_state);
/* LOCKING */
if (break_state)
@@ -637,14 +579,13 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
}
#endif
-static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file)
+static int klsi_105_tiocmget(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
struct klsi_105_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
int rc;
unsigned long line_state;
- dbg("%s - request, just guessing", __func__);
rc = klsi_105_get_line_state(port, &line_state);
if (rc < 0) {
@@ -657,17 +598,15 @@ static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file)
spin_lock_irqsave(&priv->lock, flags);
priv->line_state = line_state;
spin_unlock_irqrestore(&priv->lock, flags);
- dbg("%s - read line state 0x%lx", __func__, line_state);
+ dev_dbg(&port->dev, "%s - read line state 0x%lx\n", __func__, line_state);
return (int)line_state;
}
-static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file,
+static int klsi_105_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear)
{
int retval = -EINVAL;
- dbg("%s", __func__);
-
/* if this ever gets implemented, it should be done something like this:
struct usb_serial *serial = port->serial;
struct klsi_105_private *priv = usb_get_serial_port_data(port);
@@ -690,40 +629,8 @@ static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file,
return retval;
}
-
-static int __init klsi_105_init(void)
-{
- int retval;
- retval = usb_serial_register(&kl5kusb105d_device);
- if (retval)
- goto failed_usb_serial_register;
- retval = usb_register(&kl5kusb105d_driver);
- if (retval)
- goto failed_usb_register;
-
- printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
- DRIVER_DESC "\n");
- return 0;
-failed_usb_register:
- usb_serial_deregister(&kl5kusb105d_device);
-failed_usb_serial_register:
- return retval;
-}
-
-static void __exit klsi_105_exit(void)
-{
- usb_deregister(&kl5kusb105d_driver);
- usb_serial_deregister(&kl5kusb105d_device);
-}
-
-
-module_init(klsi_105_init);
-module_exit(klsi_105_exit);
+module_usb_serial_driver(serial_drivers, id_table);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-
-
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "enable extensive debugging messages");