diff options
Diffstat (limited to 'drivers/usb/serial/kl5kusb105.c')
| -rw-r--r-- | drivers/usb/serial/kl5kusb105.c | 241 |
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"); |
