Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes...
[pandora-kernel.git] / drivers / usb / serial / mct_u232.c
1 /*
2  * MCT (Magic Control Technology Corp.) USB RS232 Converter Driver
3  *
4  *   Copyright (C) 2000 Wolfgang Grandegger (wolfgang@ces.ch)
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  * This program is largely derived from the Belkin USB Serial Adapter Driver
12  * (see belkin_sa.[ch]). All of the information about the device was acquired
13  * by using SniffUSB on Windows98. For technical details see mct_u232.h.
14  *
15  * William G. Greathouse and Greg Kroah-Hartman provided great help on how to
16  * do the reverse engineering and how to write a USB serial device driver.
17  *
18  * TO BE DONE, TO BE CHECKED:
19  *   DTR/RTS signal handling may be incomplete or incorrect. I have mainly
20  *   implemented what I have seen with SniffUSB or found in belkin_sa.c.
21  *   For further TODOs check also belkin_sa.c.
22  *
23  * TEST STATUS:
24  *   Basic tests have been performed with minicom/zmodem transfers and
25  *   modem dialing under Linux 2.4.0-test10 (for me it works fine).
26  *
27  * 04-Nov-2003 Bill Marr <marr at flex dot com>
28  *   - Mimic Windows driver by sending 2 USB 'device request' messages
29  *     following normal 'baud rate change' message.  This allows data to be
30  *     transmitted to RS-232 devices which don't assert the 'CTS' signal.
31  *
32  * 10-Nov-2001 Wolfgang Grandegger
33  *   - Fixed an endianess problem with the baudrate selection for PowerPC.
34  *
35  * 06-Dec-2001 Martin Hamilton <martinh@gnu.org>
36  *   - Added support for the Belkin F5U109 DB9 adaptor
37  *
38  * 30-May-2001 Greg Kroah-Hartman
39  *   - switched from using spinlock to a semaphore, which fixes lots of
40  *     problems.
41  *
42  * 04-May-2001 Stelian Pop
43  *   - Set the maximum bulk output size for Sitecom U232-P25 model to 16 bytes
44  *     instead of the device reported 32 (using 32 bytes causes many data
45  *     loss, Windows driver uses 16 too).
46  *
47  * 02-May-2001 Stelian Pop
48  *   - Fixed the baud calculation for Sitecom U232-P25 model
49  *
50  * 08-Apr-2001 gb
51  *   - Identify version on module load.
52  *
53  * 06-Jan-2001 Cornel Ciocirlan
54  *   - Added support for Sitecom U232-P25 model (Product Id 0x0230)
55  *   - Added support for D-Link DU-H3SP USB BAY (Product Id 0x0200)
56  *
57  * 29-Nov-2000 Greg Kroah-Hartman
58  *   - Added device id table to fit with 2.4.0-test11 structure.
59  *   - took out DEAL_WITH_TWO_INT_IN_ENDPOINTS #define as it's not needed
60  *     (lots of things will change if/when the usb-serial core changes to
61  *     handle these issues.
62  *
63  * 27-Nov-2000 Wolfgang Grandegge
64  *   A version for kernel 2.4.0-test10 released to the Linux community
65  *   (via linux-usb-devel).
66  */
67
68 #include <linux/kernel.h>
69 #include <linux/errno.h>
70 #include <linux/init.h>
71 #include <linux/slab.h>
72 #include <linux/tty.h>
73 #include <linux/tty_driver.h>
74 #include <linux/tty_flip.h>
75 #include <linux/module.h>
76 #include <linux/spinlock.h>
77 #include <linux/uaccess.h>
78 #include <asm/unaligned.h>
79 #include <linux/usb.h>
80 #include <linux/usb/serial.h>
81 #include "mct_u232.h"
82
83 /*
84  * Version Information
85  */
86 #define DRIVER_VERSION "z2.1"           /* Linux in-kernel version */
87 #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
88 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
89
90 static int debug;
91
92 /*
93  * Function prototypes
94  */
95 static int  mct_u232_startup(struct usb_serial *serial);
96 static void mct_u232_release(struct usb_serial *serial);
97 static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);
98 static void mct_u232_close(struct usb_serial_port *port);
99 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on);
100 static void mct_u232_read_int_callback(struct urb *urb);
101 static void mct_u232_set_termios(struct tty_struct *tty,
102                         struct usb_serial_port *port, struct ktermios *old);
103 static void mct_u232_break_ctl(struct tty_struct *tty, int break_state);
104 static int  mct_u232_tiocmget(struct tty_struct *tty, struct file *file);
105 static int  mct_u232_tiocmset(struct tty_struct *tty, struct file *file,
106                         unsigned int set, unsigned int clear);
107 static void mct_u232_throttle(struct tty_struct *tty);
108 static void mct_u232_unthrottle(struct tty_struct *tty);
109
110
111 /*
112  * All of the device info needed for the MCT USB-RS232 converter.
113  */
114 static const struct usb_device_id id_table_combined[] = {
115         { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
116         { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
117         { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
118         { USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },
119         { }             /* Terminating entry */
120 };
121
122 MODULE_DEVICE_TABLE(usb, id_table_combined);
123
124 static struct usb_driver mct_u232_driver = {
125         .name =         "mct_u232",
126         .probe =        usb_serial_probe,
127         .disconnect =   usb_serial_disconnect,
128         .id_table =     id_table_combined,
129         .no_dynamic_id =        1,
130 };
131
132 static struct usb_serial_driver mct_u232_device = {
133         .driver = {
134                 .owner =        THIS_MODULE,
135                 .name =         "mct_u232",
136         },
137         .description =       "MCT U232",
138         .usb_driver =        &mct_u232_driver,
139         .id_table =          id_table_combined,
140         .num_ports =         1,
141         .open =              mct_u232_open,
142         .close =             mct_u232_close,
143         .dtr_rts =           mct_u232_dtr_rts,
144         .throttle =          mct_u232_throttle,
145         .unthrottle =        mct_u232_unthrottle,
146         .read_int_callback = mct_u232_read_int_callback,
147         .set_termios =       mct_u232_set_termios,
148         .break_ctl =         mct_u232_break_ctl,
149         .tiocmget =          mct_u232_tiocmget,
150         .tiocmset =          mct_u232_tiocmset,
151         .attach =            mct_u232_startup,
152         .release =           mct_u232_release,
153 };
154
155
156 struct mct_u232_private {
157         spinlock_t lock;
158         unsigned int         control_state; /* Modem Line Setting (TIOCM) */
159         unsigned char        last_lcr;      /* Line Control Register */
160         unsigned char        last_lsr;      /* Line Status Register */
161         unsigned char        last_msr;      /* Modem Status Register */
162         unsigned int         rx_flags;      /* Throttling flags */
163 };
164
165 #define THROTTLED               0x01
166
167 /*
168  * Handle vendor specific USB requests
169  */
170
171 #define WDR_TIMEOUT 5000 /* default urb timeout */
172
173 /*
174  * Later day 2.6.0-test kernels have new baud rates like B230400 which
175  * we do not know how to support. We ignore them for the moment.
176  */
177 static int mct_u232_calculate_baud_rate(struct usb_serial *serial,
178                                         speed_t value, speed_t *result)
179 {
180         *result = value;
181
182         if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
183                 || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
184                 switch (value) {
185                 case 300:
186                         return 0x01;
187                 case 600:
188                         return 0x02; /* this one not tested */
189                 case 1200:
190                         return 0x03;
191                 case 2400:
192                         return 0x04;
193                 case 4800:
194                         return 0x06;
195                 case 9600:
196                         return 0x08;
197                 case 19200:
198                         return 0x09;
199                 case 38400:
200                         return 0x0a;
201                 case 57600:
202                         return 0x0b;
203                 case 115200:
204                         return 0x0c;
205                 default:
206                         *result = 9600;
207                         return 0x08;
208                 }
209         } else {
210                 /* FIXME: Can we use any divider - should we do
211                    divider = 115200/value;
212                    real baud = 115200/divider */
213                 switch (value) {
214                 case 300: break;
215                 case 600: break;
216                 case 1200: break;
217                 case 2400: break;
218                 case 4800: break;
219                 case 9600: break;
220                 case 19200: break;
221                 case 38400: break;
222                 case 57600: break;
223                 case 115200: break;
224                 default:
225                         value = 9600;
226                         *result = 9600;
227                 }
228                 return 115200/value;
229         }
230 }
231
232 static int mct_u232_set_baud_rate(struct tty_struct *tty,
233         struct usb_serial *serial, struct usb_serial_port *port, speed_t value)
234 {
235         unsigned int divisor;
236         int rc;
237         unsigned char *buf;
238         unsigned char cts_enable_byte = 0;
239         speed_t speed;
240
241         buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
242         if (buf == NULL)
243                 return -ENOMEM;
244
245         divisor = mct_u232_calculate_baud_rate(serial, value, &speed);
246         put_unaligned_le32(cpu_to_le32(divisor), buf);
247         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
248                                 MCT_U232_SET_BAUD_RATE_REQUEST,
249                                 MCT_U232_SET_REQUEST_TYPE,
250                                 0, 0, buf, MCT_U232_SET_BAUD_RATE_SIZE,
251                                 WDR_TIMEOUT);
252         if (rc < 0)     /*FIXME: What value speed results */
253                 dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n",
254                         value, rc);
255         else
256                 tty_encode_baud_rate(tty, speed, speed);
257         dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor);
258
259         /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
260            always sends two extra USB 'device request' messages after the
261            'baud rate change' message.  The actual functionality of the
262            request codes in these messages is not fully understood but these
263            particular codes are never seen in any operation besides a baud
264            rate change.  Both of these messages send a single byte of data.
265            In the first message, the value of this byte is always zero.
266
267            The second message has been determined experimentally to control
268            whether data will be transmitted to a device which is not asserting
269            the 'CTS' signal.  If the second message's data byte is zero, data
270            will be transmitted even if 'CTS' is not asserted (i.e. no hardware
271            flow control).  if the second message's data byte is nonzero (a
272            value of 1 is used by this driver), data will not be transmitted to
273            a device which is not asserting 'CTS'.
274         */
275
276         buf[0] = 0;
277         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
278                                 MCT_U232_SET_UNKNOWN1_REQUEST,
279                                 MCT_U232_SET_REQUEST_TYPE,
280                                 0, 0, buf, MCT_U232_SET_UNKNOWN1_SIZE,
281                                 WDR_TIMEOUT);
282         if (rc < 0)
283                 dev_err(&port->dev, "Sending USB device request code %d "
284                         "failed (error = %d)\n", MCT_U232_SET_UNKNOWN1_REQUEST,
285                         rc);
286
287         if (port && C_CRTSCTS(tty))
288            cts_enable_byte = 1;
289
290         dbg("set_baud_rate: send second control message, data = %02X",
291                                                         cts_enable_byte);
292         buf[0] = cts_enable_byte;
293         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
294                         MCT_U232_SET_CTS_REQUEST,
295                         MCT_U232_SET_REQUEST_TYPE,
296                         0, 0, buf, MCT_U232_SET_CTS_SIZE,
297                         WDR_TIMEOUT);
298         if (rc < 0)
299                 dev_err(&port->dev, "Sending USB device request code %d "
300                         "failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc);
301
302         kfree(buf);
303         return rc;
304 } /* mct_u232_set_baud_rate */
305
306 static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr)
307 {
308         int rc;
309         unsigned char *buf;
310
311         buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
312         if (buf == NULL)
313                 return -ENOMEM;
314
315         buf[0] = lcr;
316         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
317                         MCT_U232_SET_LINE_CTRL_REQUEST,
318                         MCT_U232_SET_REQUEST_TYPE,
319                         0, 0, buf, MCT_U232_SET_LINE_CTRL_SIZE,
320                         WDR_TIMEOUT);
321         if (rc < 0)
322                 dev_err(&serial->dev->dev,
323                         "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc);
324         dbg("set_line_ctrl: 0x%x", lcr);
325         kfree(buf);
326         return rc;
327 } /* mct_u232_set_line_ctrl */
328
329 static int mct_u232_set_modem_ctrl(struct usb_serial *serial,
330                                    unsigned int control_state)
331 {
332         int rc;
333         unsigned char mcr;
334         unsigned char *buf;
335
336         buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
337         if (buf == NULL)
338                 return -ENOMEM;
339
340         mcr = MCT_U232_MCR_NONE;
341         if (control_state & TIOCM_DTR)
342                 mcr |= MCT_U232_MCR_DTR;
343         if (control_state & TIOCM_RTS)
344                 mcr |= MCT_U232_MCR_RTS;
345
346         buf[0] = mcr;
347         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
348                         MCT_U232_SET_MODEM_CTRL_REQUEST,
349                         MCT_U232_SET_REQUEST_TYPE,
350                         0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE,
351                         WDR_TIMEOUT);
352         if (rc < 0)
353                 dev_err(&serial->dev->dev,
354                         "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc);
355         dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr);
356
357         kfree(buf);
358         return rc;
359 } /* mct_u232_set_modem_ctrl */
360
361 static int mct_u232_get_modem_stat(struct usb_serial *serial,
362                                                 unsigned char *msr)
363 {
364         int rc;
365         unsigned char *buf;
366
367         buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
368         if (buf == NULL) {
369                 *msr = 0;
370                 return -ENOMEM;
371         }
372         rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
373                         MCT_U232_GET_MODEM_STAT_REQUEST,
374                         MCT_U232_GET_REQUEST_TYPE,
375                         0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE,
376                         WDR_TIMEOUT);
377         if (rc < 0) {
378                 dev_err(&serial->dev->dev,
379                         "Get MODEM STATus failed (error = %d)\n", rc);
380                 *msr = 0;
381         } else {
382                 *msr = buf[0];
383         }
384         dbg("get_modem_stat: 0x%x", *msr);
385         kfree(buf);
386         return rc;
387 } /* mct_u232_get_modem_stat */
388
389 static void mct_u232_msr_to_state(unsigned int *control_state,
390                                                 unsigned char msr)
391 {
392         /* Translate Control Line states */
393         if (msr & MCT_U232_MSR_DSR)
394                 *control_state |=  TIOCM_DSR;
395         else
396                 *control_state &= ~TIOCM_DSR;
397         if (msr & MCT_U232_MSR_CTS)
398                 *control_state |=  TIOCM_CTS;
399         else
400                 *control_state &= ~TIOCM_CTS;
401         if (msr & MCT_U232_MSR_RI)
402                 *control_state |=  TIOCM_RI;
403         else
404                 *control_state &= ~TIOCM_RI;
405         if (msr & MCT_U232_MSR_CD)
406                 *control_state |=  TIOCM_CD;
407         else
408                 *control_state &= ~TIOCM_CD;
409         dbg("msr_to_state: msr=0x%x ==> state=0x%x", msr, *control_state);
410 } /* mct_u232_msr_to_state */
411
412 /*
413  * Driver's tty interface functions
414  */
415
416 static int mct_u232_startup(struct usb_serial *serial)
417 {
418         struct mct_u232_private *priv;
419         struct usb_serial_port *port, *rport;
420
421         priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
422         if (!priv)
423                 return -ENOMEM;
424         spin_lock_init(&priv->lock);
425         usb_set_serial_port_data(serial->port[0], priv);
426
427         init_waitqueue_head(&serial->port[0]->write_wait);
428
429         /* Puh, that's dirty */
430         port = serial->port[0];
431         rport = serial->port[1];
432         /* No unlinking, it wasn't submitted yet. */
433         usb_free_urb(port->read_urb);
434         port->read_urb = rport->interrupt_in_urb;
435         rport->interrupt_in_urb = NULL;
436         port->read_urb->context = port;
437
438         return 0;
439 } /* mct_u232_startup */
440
441
442 static void mct_u232_release(struct usb_serial *serial)
443 {
444         struct mct_u232_private *priv;
445         int i;
446
447         dbg("%s", __func__);
448
449         for (i = 0; i < serial->num_ports; ++i) {
450                 /* My special items, the standard routines free my urbs */
451                 priv = usb_get_serial_port_data(serial->port[i]);
452                 kfree(priv);
453         }
454 } /* mct_u232_release */
455
456 static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
457 {
458         struct usb_serial *serial = port->serial;
459         struct mct_u232_private *priv = usb_get_serial_port_data(port);
460         int retval = 0;
461         unsigned int control_state;
462         unsigned long flags;
463         unsigned char last_lcr;
464         unsigned char last_msr;
465
466         dbg("%s port %d", __func__, port->number);
467
468         /* Compensate for a hardware bug: although the Sitecom U232-P25
469          * device reports a maximum output packet size of 32 bytes,
470          * it seems to be able to accept only 16 bytes (and that's what
471          * SniffUSB says too...)
472          */
473         if (le16_to_cpu(serial->dev->descriptor.idProduct)
474                                                 == MCT_U232_SITECOM_PID)
475                 port->bulk_out_size = 16;
476
477         /* Do a defined restart: the normal serial device seems to
478          * always turn on DTR and RTS here, so do the same. I'm not
479          * sure if this is really necessary. But it should not harm
480          * either.
481          */
482         spin_lock_irqsave(&priv->lock, flags);
483         if (tty && (tty->termios->c_cflag & CBAUD))
484                 priv->control_state = TIOCM_DTR | TIOCM_RTS;
485         else
486                 priv->control_state = 0;
487
488         priv->last_lcr = (MCT_U232_DATA_BITS_8 |
489                           MCT_U232_PARITY_NONE |
490                           MCT_U232_STOP_BITS_1);
491         control_state = priv->control_state;
492         last_lcr = priv->last_lcr;
493         spin_unlock_irqrestore(&priv->lock, flags);
494         mct_u232_set_modem_ctrl(serial, control_state);
495         mct_u232_set_line_ctrl(serial, last_lcr);
496
497         /* Read modem status and update control state */
498         mct_u232_get_modem_stat(serial, &last_msr);
499         spin_lock_irqsave(&priv->lock, flags);
500         priv->last_msr = last_msr;
501         mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
502         spin_unlock_irqrestore(&priv->lock, flags);
503
504         port->read_urb->dev = port->serial->dev;
505         retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
506         if (retval) {
507                 dev_err(&port->dev,
508                         "usb_submit_urb(read bulk) failed pipe 0x%x err %d\n",
509                         port->read_urb->pipe, retval);
510                 goto error;
511         }
512
513         port->interrupt_in_urb->dev = port->serial->dev;
514         retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
515         if (retval) {
516                 usb_kill_urb(port->read_urb);
517                 dev_err(&port->dev,
518                         "usb_submit_urb(read int) failed pipe 0x%x err %d",
519                         port->interrupt_in_urb->pipe, retval);
520                 goto error;
521         }
522         return 0;
523
524 error:
525         return retval;
526 } /* mct_u232_open */
527
528 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on)
529 {
530         unsigned int control_state;
531         struct mct_u232_private *priv = usb_get_serial_port_data(port);
532
533         mutex_lock(&port->serial->disc_mutex);
534         if (!port->serial->disconnected) {
535                 /* drop DTR and RTS */
536                 spin_lock_irq(&priv->lock);
537                 if (on)
538                         priv->control_state |= TIOCM_DTR | TIOCM_RTS;
539                 else
540                         priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
541                 control_state = priv->control_state;
542                 spin_unlock_irq(&priv->lock);
543                 mct_u232_set_modem_ctrl(port->serial, control_state);
544         }
545         mutex_unlock(&port->serial->disc_mutex);
546 }
547
548 static void mct_u232_close(struct usb_serial_port *port)
549 {
550         dbg("%s port %d", __func__, port->number);
551
552         usb_serial_generic_close(port);
553         if (port->serial->dev)
554                 usb_kill_urb(port->interrupt_in_urb);
555 } /* mct_u232_close */
556
557
558 static void mct_u232_read_int_callback(struct urb *urb)
559 {
560         struct usb_serial_port *port = urb->context;
561         struct mct_u232_private *priv = usb_get_serial_port_data(port);
562         struct usb_serial *serial = port->serial;
563         struct tty_struct *tty;
564         unsigned char *data = urb->transfer_buffer;
565         int retval;
566         int status = urb->status;
567         unsigned long flags;
568
569         switch (status) {
570         case 0:
571                 /* success */
572                 break;
573         case -ECONNRESET:
574         case -ENOENT:
575         case -ESHUTDOWN:
576                 /* this urb is terminated, clean up */
577                 dbg("%s - urb shutting down with status: %d",
578                     __func__, status);
579                 return;
580         default:
581                 dbg("%s - nonzero urb status received: %d",
582                     __func__, status);
583                 goto exit;
584         }
585
586         if (!serial) {
587                 dbg("%s - bad serial pointer, exiting", __func__);
588                 return;
589         }
590
591         dbg("%s - port %d", __func__, port->number);
592         usb_serial_debug_data(debug, &port->dev, __func__,
593                                         urb->actual_length, data);
594
595         /*
596          * Work-a-round: handle the 'usual' bulk-in pipe here
597          */
598         if (urb->transfer_buffer_length > 2) {
599                 if (urb->actual_length) {
600                         tty = tty_port_tty_get(&port->port);
601                         if (tty) {
602                                 tty_insert_flip_string(tty, data,
603                                                 urb->actual_length);
604                                 tty_flip_buffer_push(tty);
605                         }
606                         tty_kref_put(tty);
607                 }
608                 goto exit;
609         }
610
611         /*
612          * The interrupt-in pipe signals exceptional conditions (modem line
613          * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
614          */
615         spin_lock_irqsave(&priv->lock, flags);
616         priv->last_msr = data[MCT_U232_MSR_INDEX];
617
618         /* Record Control Line states */
619         mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
620
621 #if 0
622         /* Not yet handled. See belkin_sa.c for further information */
623         /* Now to report any errors */
624         priv->last_lsr = data[MCT_U232_LSR_INDEX];
625         /*
626          * fill in the flip buffer here, but I do not know the relation
627          * to the current/next receive buffer or characters.  I need
628          * to look in to this before committing any code.
629          */
630         if (priv->last_lsr & MCT_U232_LSR_ERR) {
631                 tty = tty_port_tty_get(&port->port);
632                 /* Overrun Error */
633                 if (priv->last_lsr & MCT_U232_LSR_OE) {
634                 }
635                 /* Parity Error */
636                 if (priv->last_lsr & MCT_U232_LSR_PE) {
637                 }
638                 /* Framing Error */
639                 if (priv->last_lsr & MCT_U232_LSR_FE) {
640                 }
641                 /* Break Indicator */
642                 if (priv->last_lsr & MCT_U232_LSR_BI) {
643                 }
644                 tty_kref_put(tty);
645         }
646 #endif
647         spin_unlock_irqrestore(&priv->lock, flags);
648 exit:
649         retval = usb_submit_urb(urb, GFP_ATOMIC);
650         if (retval)
651                 dev_err(&port->dev,
652                         "%s - usb_submit_urb failed with result %d\n",
653                         __func__, retval);
654 } /* mct_u232_read_int_callback */
655
656 static void mct_u232_set_termios(struct tty_struct *tty,
657                                  struct usb_serial_port *port,
658                                  struct ktermios *old_termios)
659 {
660         struct usb_serial *serial = port->serial;
661         struct mct_u232_private *priv = usb_get_serial_port_data(port);
662         struct ktermios *termios = tty->termios;
663         unsigned int cflag = termios->c_cflag;
664         unsigned int old_cflag = old_termios->c_cflag;
665         unsigned long flags;
666         unsigned int control_state;
667         unsigned char last_lcr;
668
669         /* get a local copy of the current port settings */
670         spin_lock_irqsave(&priv->lock, flags);
671         control_state = priv->control_state;
672         spin_unlock_irqrestore(&priv->lock, flags);
673         last_lcr = 0;
674
675         /*
676          * Update baud rate.
677          * Do not attempt to cache old rates and skip settings,
678          * disconnects screw such tricks up completely.
679          * Premature optimization is the root of all evil.
680          */
681
682         /* reassert DTR and RTS on transition from B0 */
683         if ((old_cflag & CBAUD) == B0) {
684                 dbg("%s: baud was B0", __func__);
685                 control_state |= TIOCM_DTR | TIOCM_RTS;
686                 mct_u232_set_modem_ctrl(serial, control_state);
687         }
688
689         mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty));
690
691         if ((cflag & CBAUD) == B0) {
692                 dbg("%s: baud is B0", __func__);
693                 /* Drop RTS and DTR */
694                 control_state &= ~(TIOCM_DTR | TIOCM_RTS);
695                 mct_u232_set_modem_ctrl(serial, control_state);
696         }
697
698         /*
699          * Update line control register (LCR)
700          */
701
702         /* set the parity */
703         if (cflag & PARENB)
704                 last_lcr |= (cflag & PARODD) ?
705                         MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
706         else
707                 last_lcr |= MCT_U232_PARITY_NONE;
708
709         /* set the number of data bits */
710         switch (cflag & CSIZE) {
711         case CS5:
712                 last_lcr |= MCT_U232_DATA_BITS_5; break;
713         case CS6:
714                 last_lcr |= MCT_U232_DATA_BITS_6; break;
715         case CS7:
716                 last_lcr |= MCT_U232_DATA_BITS_7; break;
717         case CS8:
718                 last_lcr |= MCT_U232_DATA_BITS_8; break;
719         default:
720                 dev_err(&port->dev,
721                         "CSIZE was not CS5-CS8, using default of 8\n");
722                 last_lcr |= MCT_U232_DATA_BITS_8;
723                 break;
724         }
725
726         termios->c_cflag &= ~CMSPAR;
727
728         /* set the number of stop bits */
729         last_lcr |= (cflag & CSTOPB) ?
730                 MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
731
732         mct_u232_set_line_ctrl(serial, last_lcr);
733
734         /* save off the modified port settings */
735         spin_lock_irqsave(&priv->lock, flags);
736         priv->control_state = control_state;
737         priv->last_lcr = last_lcr;
738         spin_unlock_irqrestore(&priv->lock, flags);
739 } /* mct_u232_set_termios */
740
741 static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
742 {
743         struct usb_serial_port *port = tty->driver_data;
744         struct usb_serial *serial = port->serial;
745         struct mct_u232_private *priv = usb_get_serial_port_data(port);
746         unsigned char lcr;
747         unsigned long flags;
748
749         dbg("%sstate=%d", __func__, break_state);
750
751         spin_lock_irqsave(&priv->lock, flags);
752         lcr = priv->last_lcr;
753
754         if (break_state)
755                 lcr |= MCT_U232_SET_BREAK;
756         spin_unlock_irqrestore(&priv->lock, flags);
757
758         mct_u232_set_line_ctrl(serial, lcr);
759 } /* mct_u232_break_ctl */
760
761
762 static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file)
763 {
764         struct usb_serial_port *port = tty->driver_data;
765         struct mct_u232_private *priv = usb_get_serial_port_data(port);
766         unsigned int control_state;
767         unsigned long flags;
768
769         dbg("%s", __func__);
770
771         spin_lock_irqsave(&priv->lock, flags);
772         control_state = priv->control_state;
773         spin_unlock_irqrestore(&priv->lock, flags);
774
775         return control_state;
776 }
777
778 static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file,
779                               unsigned int set, unsigned int clear)
780 {
781         struct usb_serial_port *port = tty->driver_data;
782         struct usb_serial *serial = port->serial;
783         struct mct_u232_private *priv = usb_get_serial_port_data(port);
784         unsigned int control_state;
785         unsigned long flags;
786
787         dbg("%s", __func__);
788
789         spin_lock_irqsave(&priv->lock, flags);
790         control_state = priv->control_state;
791
792         if (set & TIOCM_RTS)
793                 control_state |= TIOCM_RTS;
794         if (set & TIOCM_DTR)
795                 control_state |= TIOCM_DTR;
796         if (clear & TIOCM_RTS)
797                 control_state &= ~TIOCM_RTS;
798         if (clear & TIOCM_DTR)
799                 control_state &= ~TIOCM_DTR;
800
801         priv->control_state = control_state;
802         spin_unlock_irqrestore(&priv->lock, flags);
803         return mct_u232_set_modem_ctrl(serial, control_state);
804 }
805
806 static void mct_u232_throttle(struct tty_struct *tty)
807 {
808         struct usb_serial_port *port = tty->driver_data;
809         struct mct_u232_private *priv = usb_get_serial_port_data(port);
810         unsigned int control_state;
811
812         dbg("%s - port %d", __func__, port->number);
813
814         spin_lock_irq(&priv->lock);
815         priv->rx_flags |= THROTTLED;
816         if (C_CRTSCTS(tty)) {
817                 priv->control_state &= ~TIOCM_RTS;
818                 control_state = priv->control_state;
819                 spin_unlock_irq(&priv->lock);
820                 (void) mct_u232_set_modem_ctrl(port->serial, control_state);
821         } else {
822                 spin_unlock_irq(&priv->lock);
823         }
824 }
825
826
827 static void mct_u232_unthrottle(struct tty_struct *tty)
828 {
829         struct usb_serial_port *port = tty->driver_data;
830         struct mct_u232_private *priv = usb_get_serial_port_data(port);
831         unsigned int control_state;
832
833         dbg("%s - port %d", __func__, port->number);
834
835         spin_lock_irq(&priv->lock);
836         if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
837                 priv->rx_flags &= ~THROTTLED;
838                 priv->control_state |= TIOCM_RTS;
839                 control_state = priv->control_state;
840                 spin_unlock_irq(&priv->lock);
841                 (void) mct_u232_set_modem_ctrl(port->serial, control_state);
842         } else {
843                 spin_unlock_irq(&priv->lock);
844         }
845 }
846
847 static int __init mct_u232_init(void)
848 {
849         int retval;
850         retval = usb_serial_register(&mct_u232_device);
851         if (retval)
852                 goto failed_usb_serial_register;
853         retval = usb_register(&mct_u232_driver);
854         if (retval)
855                 goto failed_usb_register;
856         printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
857                DRIVER_DESC "\n");
858         return 0;
859 failed_usb_register:
860         usb_serial_deregister(&mct_u232_device);
861 failed_usb_serial_register:
862         return retval;
863 }
864
865
866 static void __exit mct_u232_exit(void)
867 {
868         usb_deregister(&mct_u232_driver);
869         usb_serial_deregister(&mct_u232_device);
870 }
871
872 module_init(mct_u232_init);
873 module_exit(mct_u232_exit);
874
875 MODULE_AUTHOR(DRIVER_AUTHOR);
876 MODULE_DESCRIPTION(DRIVER_DESC);
877 MODULE_LICENSE("GPL");
878
879 module_param(debug, bool, S_IRUGO | S_IWUSR);
880 MODULE_PARM_DESC(debug, "Debug enabled or not");