]> git.karo-electronics.de Git - linux-beck.git/blob - drivers/usb/serial/kl5kusb105.c
Merge tag 'timer' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[linux-beck.git] / drivers / usb / serial / kl5kusb105.c
1 /*
2  * KLSI KL5KUSB105 chip RS232 converter driver
3  *
4  *   Copyright (C) 2010 Johan Hovold <jhovold@gmail.com>
5  *   Copyright (C) 2001 Utz-Uwe Haus <haus@uuhaus.de>
6  *
7  *   This program is free software; you can redistribute it and/or modify
8  *   it under the terms of the GNU General Public License as published by
9  *   the Free Software Foundation; either version 2 of the License, or
10  *   (at your option) any later version.
11  *
12  * All information about the device was acquired using SniffUSB ans snoopUSB
13  * on Windows98.
14  * It was written out of frustration with the PalmConnect USB Serial adapter
15  * sold by Palm Inc.
16  * Neither Palm, nor their contractor (MCCI) or their supplier (KLSI) provided
17  * information that was not already available.
18  *
19  * It seems that KLSI bought some silicon-design information from ScanLogic,
20  * whose SL11R processor is at the core of the KL5KUSB chipset from KLSI.
21  * KLSI has firmware available for their devices; it is probable that the
22  * firmware differs from that used by KLSI in their products. If you have an
23  * original KLSI device and can provide some information on it, I would be
24  * most interested in adding support for it here. If you have any information
25  * on the protocol used (or find errors in my reverse-engineered stuff), please
26  * let me know.
27  *
28  * The code was only tested with a PalmConnect USB adapter; if you
29  * are adventurous, try it with any KLSI-based device and let me know how it
30  * breaks so that I can fix it!
31  */
32
33 /* TODO:
34  *      check modem line signals
35  *      implement handshaking or decide that we do not support it
36  */
37
38 #include <linux/kernel.h>
39 #include <linux/errno.h>
40 #include <linux/init.h>
41 #include <linux/slab.h>
42 #include <linux/tty.h>
43 #include <linux/tty_driver.h>
44 #include <linux/tty_flip.h>
45 #include <linux/module.h>
46 #include <linux/uaccess.h>
47 #include <asm/unaligned.h>
48 #include <linux/usb.h>
49 #include <linux/usb/serial.h>
50 #include "kl5kusb105.h"
51
52 static bool debug;
53
54 /*
55  * Version Information
56  */
57 #define DRIVER_VERSION "v0.4"
58 #define DRIVER_AUTHOR "Utz-Uwe Haus <haus@uuhaus.de>, Johan Hovold <jhovold@gmail.com>"
59 #define DRIVER_DESC "KLSI KL5KUSB105 chipset USB->Serial Converter driver"
60
61
62 /*
63  * Function prototypes
64  */
65 static int  klsi_105_startup(struct usb_serial *serial);
66 static void klsi_105_release(struct usb_serial *serial);
67 static int  klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port);
68 static void klsi_105_close(struct usb_serial_port *port);
69 static void klsi_105_set_termios(struct tty_struct *tty,
70                         struct usb_serial_port *port, struct ktermios *old);
71 static int  klsi_105_tiocmget(struct tty_struct *tty);
72 static int  klsi_105_tiocmset(struct tty_struct *tty,
73                         unsigned int set, unsigned int clear);
74 static void klsi_105_process_read_urb(struct urb *urb);
75 static int klsi_105_prepare_write_buffer(struct usb_serial_port *port,
76                                                 void *dest, size_t size);
77
78 /*
79  * All of the device info needed for the KLSI converters.
80  */
81 static const struct usb_device_id id_table[] = {
82         { USB_DEVICE(PALMCONNECT_VID, PALMCONNECT_PID) },
83         { USB_DEVICE(KLSI_VID, KLSI_KL5KUSB105D_PID) },
84         { }             /* Terminating entry */
85 };
86
87 MODULE_DEVICE_TABLE(usb, id_table);
88
89 static struct usb_driver kl5kusb105d_driver = {
90         .name =         "kl5kusb105d",
91         .probe =        usb_serial_probe,
92         .disconnect =   usb_serial_disconnect,
93         .id_table =     id_table,
94 };
95
96 static struct usb_serial_driver kl5kusb105d_device = {
97         .driver = {
98                 .owner =        THIS_MODULE,
99                 .name =         "kl5kusb105d",
100         },
101         .description =          "KL5KUSB105D / PalmConnect",
102         .id_table =             id_table,
103         .num_ports =            1,
104         .bulk_out_size =        64,
105         .open =                 klsi_105_open,
106         .close =                klsi_105_close,
107         .set_termios =          klsi_105_set_termios,
108         /*.break_ctl =          klsi_105_break_ctl,*/
109         .tiocmget =             klsi_105_tiocmget,
110         .tiocmset =             klsi_105_tiocmset,
111         .attach =               klsi_105_startup,
112         .release =              klsi_105_release,
113         .throttle =             usb_serial_generic_throttle,
114         .unthrottle =           usb_serial_generic_unthrottle,
115         .process_read_urb =     klsi_105_process_read_urb,
116         .prepare_write_buffer = klsi_105_prepare_write_buffer,
117 };
118
119 static struct usb_serial_driver * const serial_drivers[] = {
120         &kl5kusb105d_device, NULL
121 };
122
123 struct klsi_105_port_settings {
124         __u8    pktlen;         /* always 5, it seems */
125         __u8    baudrate;
126         __u8    databits;
127         __u8    unknown1;
128         __u8    unknown2;
129 } __attribute__ ((packed));
130
131 struct klsi_105_private {
132         struct klsi_105_port_settings   cfg;
133         struct ktermios                 termios;
134         unsigned long                   line_state; /* modem line settings */
135         spinlock_t                      lock;
136 };
137
138
139 /*
140  * Handle vendor specific USB requests
141  */
142
143
144 #define KLSI_TIMEOUT     5000 /* default urb timeout */
145
146 static int klsi_105_chg_port_settings(struct usb_serial_port *port,
147                                       struct klsi_105_port_settings *settings)
148 {
149         int rc;
150
151         rc = usb_control_msg(port->serial->dev,
152                         usb_sndctrlpipe(port->serial->dev, 0),
153                         KL5KUSB105A_SIO_SET_DATA,
154                         USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_INTERFACE,
155                         0, /* value */
156                         0, /* index */
157                         settings,
158                         sizeof(struct klsi_105_port_settings),
159                         KLSI_TIMEOUT);
160         if (rc < 0)
161                 dev_err(&port->dev,
162                         "Change port settings failed (error = %d)\n", rc);
163         dev_info(&port->serial->dev->dev,
164                  "%d byte block, baudrate %x, databits %d, u1 %d, u2 %d\n",
165                  settings->pktlen, settings->baudrate, settings->databits,
166                  settings->unknown1, settings->unknown2);
167         return rc;
168 }
169
170 /* translate a 16-bit status value from the device to linux's TIO bits */
171 static unsigned long klsi_105_status2linestate(const __u16 status)
172 {
173         unsigned long res = 0;
174
175         res =   ((status & KL5KUSB105A_DSR) ? TIOCM_DSR : 0)
176               | ((status & KL5KUSB105A_CTS) ? TIOCM_CTS : 0)
177               ;
178
179         return res;
180 }
181
182 /*
183  * Read line control via vendor command and return result through
184  * *line_state_p
185  */
186 /* It seems that the status buffer has always only 2 bytes length */
187 #define KLSI_STATUSBUF_LEN      2
188 static int klsi_105_get_line_state(struct usb_serial_port *port,
189                                    unsigned long *line_state_p)
190 {
191         int rc;
192         u8 *status_buf;
193         __u16 status;
194
195         dev_info(&port->serial->dev->dev, "sending SIO Poll request\n");
196
197         status_buf = kmalloc(KLSI_STATUSBUF_LEN, GFP_KERNEL);
198         if (!status_buf) {
199                 dev_err(&port->dev, "%s - out of memory for status buffer.\n",
200                                 __func__);
201                 return -ENOMEM;
202         }
203         status_buf[0] = 0xff;
204         status_buf[1] = 0xff;
205         rc = usb_control_msg(port->serial->dev,
206                              usb_rcvctrlpipe(port->serial->dev, 0),
207                              KL5KUSB105A_SIO_POLL,
208                              USB_TYPE_VENDOR | USB_DIR_IN,
209                              0, /* value */
210                              0, /* index */
211                              status_buf, KLSI_STATUSBUF_LEN,
212                              10000
213                              );
214         if (rc < 0)
215                 dev_err(&port->dev, "Reading line status failed (error = %d)\n",
216                         rc);
217         else {
218                 status = get_unaligned_le16(status_buf);
219
220                 dev_info(&port->serial->dev->dev, "read status %x %x",
221                          status_buf[0], status_buf[1]);
222
223                 *line_state_p = klsi_105_status2linestate(status);
224         }
225
226         kfree(status_buf);
227         return rc;
228 }
229
230
231 /*
232  * Driver's tty interface functions
233  */
234
235 static int klsi_105_startup(struct usb_serial *serial)
236 {
237         struct klsi_105_private *priv;
238         int i;
239
240         /* check if we support the product id (see keyspan.c)
241          * FIXME
242          */
243
244         /* allocate the private data structure */
245         for (i = 0; i < serial->num_ports; i++) {
246                 priv = kmalloc(sizeof(struct klsi_105_private),
247                                                    GFP_KERNEL);
248                 if (!priv) {
249                         dbg("%skmalloc for klsi_105_private failed.", __func__);
250                         i--;
251                         goto err_cleanup;
252                 }
253                 /* set initial values for control structures */
254                 priv->cfg.pktlen    = 5;
255                 priv->cfg.baudrate  = kl5kusb105a_sio_b9600;
256                 priv->cfg.databits  = kl5kusb105a_dtb_8;
257                 priv->cfg.unknown1  = 0;
258                 priv->cfg.unknown2  = 1;
259
260                 priv->line_state    = 0;
261
262                 usb_set_serial_port_data(serial->port[i], priv);
263
264                 spin_lock_init(&priv->lock);
265
266                 /* priv->termios is left uninitialized until port opening */
267                 init_waitqueue_head(&serial->port[i]->write_wait);
268         }
269
270         return 0;
271
272 err_cleanup:
273         for (; i >= 0; i--) {
274                 priv = usb_get_serial_port_data(serial->port[i]);
275                 kfree(priv);
276                 usb_set_serial_port_data(serial->port[i], NULL);
277         }
278         return -ENOMEM;
279 }
280
281 static void klsi_105_release(struct usb_serial *serial)
282 {
283         int i;
284
285         dbg("%s", __func__);
286
287         for (i = 0; i < serial->num_ports; ++i)
288                 kfree(usb_get_serial_port_data(serial->port[i]));
289 }
290
291 static int  klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
292 {
293         struct klsi_105_private *priv = usb_get_serial_port_data(port);
294         int retval = 0;
295         int rc;
296         int i;
297         unsigned long line_state;
298         struct klsi_105_port_settings *cfg;
299         unsigned long flags;
300
301         dbg("%s port %d", __func__, port->number);
302
303         /* Do a defined restart:
304          * Set up sane default baud rate and send the 'READ_ON'
305          * vendor command.
306          * FIXME: set modem line control (how?)
307          * Then read the modem line control and store values in
308          * priv->line_state.
309          */
310         cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
311         if (!cfg) {
312                 dev_err(&port->dev, "%s - out of memory for config buffer.\n",
313                                 __func__);
314                 return -ENOMEM;
315         }
316         cfg->pktlen   = 5;
317         cfg->baudrate = kl5kusb105a_sio_b9600;
318         cfg->databits = kl5kusb105a_dtb_8;
319         cfg->unknown1 = 0;
320         cfg->unknown2 = 1;
321         klsi_105_chg_port_settings(port, cfg);
322
323         /* set up termios structure */
324         spin_lock_irqsave(&priv->lock, flags);
325         priv->termios.c_iflag = tty->termios->c_iflag;
326         priv->termios.c_oflag = tty->termios->c_oflag;
327         priv->termios.c_cflag = tty->termios->c_cflag;
328         priv->termios.c_lflag = tty->termios->c_lflag;
329         for (i = 0; i < NCCS; i++)
330                 priv->termios.c_cc[i] = tty->termios->c_cc[i];
331         priv->cfg.pktlen   = cfg->pktlen;
332         priv->cfg.baudrate = cfg->baudrate;
333         priv->cfg.databits = cfg->databits;
334         priv->cfg.unknown1 = cfg->unknown1;
335         priv->cfg.unknown2 = cfg->unknown2;
336         spin_unlock_irqrestore(&priv->lock, flags);
337
338         /* READ_ON and urb submission */
339         rc = usb_serial_generic_open(tty, port);
340         if (rc) {
341                 retval = rc;
342                 goto exit;
343         }
344
345         rc = usb_control_msg(port->serial->dev,
346                              usb_sndctrlpipe(port->serial->dev, 0),
347                              KL5KUSB105A_SIO_CONFIGURE,
348                              USB_TYPE_VENDOR|USB_DIR_OUT|USB_RECIP_INTERFACE,
349                              KL5KUSB105A_SIO_CONFIGURE_READ_ON,
350                              0, /* index */
351                              NULL,
352                              0,
353                              KLSI_TIMEOUT);
354         if (rc < 0) {
355                 dev_err(&port->dev, "Enabling read failed (error = %d)\n", rc);
356                 retval = rc;
357         } else
358                 dbg("%s - enabled reading", __func__);
359
360         rc = klsi_105_get_line_state(port, &line_state);
361         if (rc >= 0) {
362                 spin_lock_irqsave(&priv->lock, flags);
363                 priv->line_state = line_state;
364                 spin_unlock_irqrestore(&priv->lock, flags);
365                 dbg("%s - read line state 0x%lx", __func__, line_state);
366                 retval = 0;
367         } else
368                 retval = rc;
369
370 exit:
371         kfree(cfg);
372         return retval;
373 }
374
375 static void klsi_105_close(struct usb_serial_port *port)
376 {
377         int rc;
378
379         dbg("%s port %d", __func__, port->number);
380
381         mutex_lock(&port->serial->disc_mutex);
382         if (!port->serial->disconnected) {
383                 /* send READ_OFF */
384                 rc = usb_control_msg(port->serial->dev,
385                                      usb_sndctrlpipe(port->serial->dev, 0),
386                                      KL5KUSB105A_SIO_CONFIGURE,
387                                      USB_TYPE_VENDOR | USB_DIR_OUT,
388                                      KL5KUSB105A_SIO_CONFIGURE_READ_OFF,
389                                      0, /* index */
390                                      NULL, 0,
391                                      KLSI_TIMEOUT);
392                 if (rc < 0)
393                         dev_err(&port->dev,
394                                 "Disabling read failed (error = %d)\n", rc);
395         }
396         mutex_unlock(&port->serial->disc_mutex);
397
398         /* shutdown our bulk reads and writes */
399         usb_serial_generic_close(port);
400
401         /* wgg - do I need this? I think so. */
402         usb_kill_urb(port->interrupt_in_urb);
403 }
404
405 /* We need to write a complete 64-byte data block and encode the
406  * number actually sent in the first double-byte, LSB-order. That
407  * leaves at most 62 bytes of payload.
408  */
409 #define KLSI_HDR_LEN            2
410 static int klsi_105_prepare_write_buffer(struct usb_serial_port *port,
411                                                 void *dest, size_t size)
412 {
413         unsigned char *buf = dest;
414         int count;
415
416         count = kfifo_out_locked(&port->write_fifo, buf + KLSI_HDR_LEN, size,
417                                                                 &port->lock);
418         put_unaligned_le16(count, buf);
419
420         return count + KLSI_HDR_LEN;
421 }
422
423 /* The data received is preceded by a length double-byte in LSB-first order.
424  */
425 static void klsi_105_process_read_urb(struct urb *urb)
426 {
427         struct usb_serial_port *port = urb->context;
428         unsigned char *data = urb->transfer_buffer;
429         struct tty_struct *tty;
430         unsigned len;
431
432         /* empty urbs seem to happen, we ignore them */
433         if (!urb->actual_length)
434                 return;
435
436         if (urb->actual_length <= KLSI_HDR_LEN) {
437                 dbg("%s - malformed packet", __func__);
438                 return;
439         }
440
441         tty = tty_port_tty_get(&port->port);
442         if (!tty)
443                 return;
444
445         len = get_unaligned_le16(data);
446         if (len > urb->actual_length - KLSI_HDR_LEN) {
447                 dbg("%s - packet length mismatch", __func__);
448                 len = urb->actual_length - KLSI_HDR_LEN;
449         }
450
451         tty_insert_flip_string(tty, data + KLSI_HDR_LEN, len);
452         tty_flip_buffer_push(tty);
453         tty_kref_put(tty);
454 }
455
456 static void klsi_105_set_termios(struct tty_struct *tty,
457                                  struct usb_serial_port *port,
458                                  struct ktermios *old_termios)
459 {
460         struct klsi_105_private *priv = usb_get_serial_port_data(port);
461         unsigned int iflag = tty->termios->c_iflag;
462         unsigned int old_iflag = old_termios->c_iflag;
463         unsigned int cflag = tty->termios->c_cflag;
464         unsigned int old_cflag = old_termios->c_cflag;
465         struct klsi_105_port_settings *cfg;
466         unsigned long flags;
467         speed_t baud;
468
469         cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
470         if (!cfg) {
471                 dev_err(&port->dev, "%s - out of memory for config buffer.\n",
472                                 __func__);
473                 return;
474         }
475
476         /* lock while we are modifying the settings */
477         spin_lock_irqsave(&priv->lock, flags);
478
479         /*
480          * Update baud rate
481          */
482         baud = tty_get_baud_rate(tty);
483
484         if ((cflag & CBAUD) != (old_cflag & CBAUD)) {
485                 /* reassert DTR and (maybe) RTS on transition from B0 */
486                 if ((old_cflag & CBAUD) == B0) {
487                         dbg("%s: baud was B0", __func__);
488 #if 0
489                         priv->control_state |= TIOCM_DTR;
490                         /* don't set RTS if using hardware flow control */
491                         if (!(old_cflag & CRTSCTS))
492                                 priv->control_state |= TIOCM_RTS;
493                         mct_u232_set_modem_ctrl(serial, priv->control_state);
494 #endif
495                 }
496         }
497         switch (baud) {
498         case 0: /* handled below */
499                 break;
500         case 1200:
501                 priv->cfg.baudrate = kl5kusb105a_sio_b1200;
502                 break;
503         case 2400:
504                 priv->cfg.baudrate = kl5kusb105a_sio_b2400;
505                 break;
506         case 4800:
507                 priv->cfg.baudrate = kl5kusb105a_sio_b4800;
508                 break;
509         case 9600:
510                 priv->cfg.baudrate = kl5kusb105a_sio_b9600;
511                 break;
512         case 19200:
513                 priv->cfg.baudrate = kl5kusb105a_sio_b19200;
514                 break;
515         case 38400:
516                 priv->cfg.baudrate = kl5kusb105a_sio_b38400;
517                 break;
518         case 57600:
519                 priv->cfg.baudrate = kl5kusb105a_sio_b57600;
520                 break;
521         case 115200:
522                 priv->cfg.baudrate = kl5kusb105a_sio_b115200;
523                 break;
524         default:
525                 dbg("KLSI USB->Serial converter:"
526                     " unsupported baudrate request, using default of 9600");
527                         priv->cfg.baudrate = kl5kusb105a_sio_b9600;
528                 baud = 9600;
529                 break;
530         }
531         if ((cflag & CBAUD) == B0) {
532                 dbg("%s: baud is B0", __func__);
533                 /* Drop RTS and DTR */
534                 /* maybe this should be simulated by sending read
535                  * disable and read enable messages?
536                  */
537                 ;
538 #if 0
539                 priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
540                 mct_u232_set_modem_ctrl(serial, priv->control_state);
541 #endif
542         }
543         tty_encode_baud_rate(tty, baud, baud);
544
545         if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
546                 /* set the number of data bits */
547                 switch (cflag & CSIZE) {
548                 case CS5:
549                         dbg("%s - 5 bits/byte not supported", __func__);
550                         spin_unlock_irqrestore(&priv->lock, flags);
551                         goto err;
552                 case CS6:
553                         dbg("%s - 6 bits/byte not supported", __func__);
554                         spin_unlock_irqrestore(&priv->lock, flags);
555                         goto err;
556                 case CS7:
557                         priv->cfg.databits = kl5kusb105a_dtb_7;
558                         break;
559                 case CS8:
560                         priv->cfg.databits = kl5kusb105a_dtb_8;
561                         break;
562                 default:
563                         dev_err(&port->dev,
564                                 "CSIZE was not CS5-CS8, using default of 8\n");
565                         priv->cfg.databits = kl5kusb105a_dtb_8;
566                         break;
567                 }
568         }
569
570         /*
571          * Update line control register (LCR)
572          */
573         if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))
574             || (cflag & CSTOPB) != (old_cflag & CSTOPB)) {
575                 /* Not currently supported */
576                 tty->termios->c_cflag &= ~(PARENB|PARODD|CSTOPB);
577 #if 0
578                 priv->last_lcr = 0;
579
580                 /* set the parity */
581                 if (cflag & PARENB)
582                         priv->last_lcr |= (cflag & PARODD) ?
583                                 MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
584                 else
585                         priv->last_lcr |= MCT_U232_PARITY_NONE;
586
587                 /* set the number of stop bits */
588                 priv->last_lcr |= (cflag & CSTOPB) ?
589                         MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
590
591                 mct_u232_set_line_ctrl(serial, priv->last_lcr);
592 #endif
593                 ;
594         }
595         /*
596          * Set flow control: well, I do not really now how to handle DTR/RTS.
597          * Just do what we have seen with SniffUSB on Win98.
598          */
599         if ((iflag & IXOFF) != (old_iflag & IXOFF)
600             || (iflag & IXON) != (old_iflag & IXON)
601             ||  (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
602                 /* Not currently supported */
603                 tty->termios->c_cflag &= ~CRTSCTS;
604                 /* Drop DTR/RTS if no flow control otherwise assert */
605 #if 0
606                 if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS))
607                         priv->control_state |= TIOCM_DTR | TIOCM_RTS;
608                 else
609                         priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
610                 mct_u232_set_modem_ctrl(serial, priv->control_state);
611 #endif
612                 ;
613         }
614         memcpy(cfg, &priv->cfg, sizeof(*cfg));
615         spin_unlock_irqrestore(&priv->lock, flags);
616
617         /* now commit changes to device */
618         klsi_105_chg_port_settings(port, cfg);
619 err:
620         kfree(cfg);
621 }
622
623 #if 0
624 static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
625 {
626         struct usb_serial_port *port = tty->driver_data;
627         struct usb_serial *serial = port->serial;
628         struct mct_u232_private *priv =
629                                 (struct mct_u232_private *)port->private;
630         unsigned char lcr = priv->last_lcr;
631
632         dbg("%sstate=%d", __func__, break_state);
633
634         /* LOCKING */
635         if (break_state)
636                 lcr |= MCT_U232_SET_BREAK;
637
638         mct_u232_set_line_ctrl(serial, lcr);
639 }
640 #endif
641
642 static int klsi_105_tiocmget(struct tty_struct *tty)
643 {
644         struct usb_serial_port *port = tty->driver_data;
645         struct klsi_105_private *priv = usb_get_serial_port_data(port);
646         unsigned long flags;
647         int rc;
648         unsigned long line_state;
649         dbg("%s - request, just guessing", __func__);
650
651         rc = klsi_105_get_line_state(port, &line_state);
652         if (rc < 0) {
653                 dev_err(&port->dev,
654                         "Reading line control failed (error = %d)\n", rc);
655                 /* better return value? EAGAIN? */
656                 return rc;
657         }
658
659         spin_lock_irqsave(&priv->lock, flags);
660         priv->line_state = line_state;
661         spin_unlock_irqrestore(&priv->lock, flags);
662         dbg("%s - read line state 0x%lx", __func__, line_state);
663         return (int)line_state;
664 }
665
666 static int klsi_105_tiocmset(struct tty_struct *tty,
667                              unsigned int set, unsigned int clear)
668 {
669         int retval = -EINVAL;
670
671         dbg("%s", __func__);
672
673 /* if this ever gets implemented, it should be done something like this:
674         struct usb_serial *serial = port->serial;
675         struct klsi_105_private *priv = usb_get_serial_port_data(port);
676         unsigned long flags;
677         int control;
678
679         spin_lock_irqsave (&priv->lock, flags);
680         if (set & TIOCM_RTS)
681                 priv->control_state |= TIOCM_RTS;
682         if (set & TIOCM_DTR)
683                 priv->control_state |= TIOCM_DTR;
684         if (clear & TIOCM_RTS)
685                 priv->control_state &= ~TIOCM_RTS;
686         if (clear & TIOCM_DTR)
687                 priv->control_state &= ~TIOCM_DTR;
688         control = priv->control_state;
689         spin_unlock_irqrestore (&priv->lock, flags);
690         retval = mct_u232_set_modem_ctrl(serial, control);
691 */
692         return retval;
693 }
694
695 module_usb_serial_driver(kl5kusb105d_driver, serial_drivers);
696
697 MODULE_AUTHOR(DRIVER_AUTHOR);
698 MODULE_DESCRIPTION(DRIVER_DESC);
699 MODULE_LICENSE("GPL");
700
701 module_param(debug, bool, S_IRUGO | S_IWUSR);
702 MODULE_PARM_DESC(debug, "enable extensive debugging messages");