Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[linux-2.6] / 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 <linux/usb.h>
79 #include <linux/usb/serial.h>
80 #include "mct_u232.h"
81
82 /*
83  * Version Information
84  */
85 #define DRIVER_VERSION "z2.1"           /* Linux in-kernel version */
86 #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
87 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
88
89 static int debug;
90
91 /*
92  * Function prototypes
93  */
94 static int  mct_u232_startup(struct usb_serial *serial);
95 static void mct_u232_shutdown(struct usb_serial *serial);
96 static int  mct_u232_open(struct tty_struct *tty,
97                         struct usb_serial_port *port, struct file *filp);
98 static void mct_u232_close(struct tty_struct *tty,
99                         struct usb_serial_port *port, struct file *filp);
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 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         .throttle =          mct_u232_throttle,
144         .unthrottle =        mct_u232_unthrottle,
145         .read_int_callback = mct_u232_read_int_callback,
146         .set_termios =       mct_u232_set_termios,
147         .break_ctl =         mct_u232_break_ctl,
148         .tiocmget =          mct_u232_tiocmget,
149         .tiocmset =          mct_u232_tiocmset,
150         .attach =            mct_u232_startup,
151         .shutdown =          mct_u232_shutdown,
152 };
153
154
155 struct mct_u232_private {
156         spinlock_t lock;
157         unsigned int         control_state; /* Modem Line Setting (TIOCM) */
158         unsigned char        last_lcr;      /* Line Control Register */
159         unsigned char        last_lsr;      /* Line Status Register */
160         unsigned char        last_msr;      /* Modem Status Register */
161         unsigned int         rx_flags;      /* Throttling flags */
162 };
163
164 #define THROTTLED               0x01
165
166 /*
167  * Handle vendor specific USB requests
168  */
169
170 #define WDR_TIMEOUT 5000 /* default urb timeout */
171
172 /*
173  * Later day 2.6.0-test kernels have new baud rates like B230400 which
174  * we do not know how to support. We ignore them for the moment.
175  */
176 static int mct_u232_calculate_baud_rate(struct usb_serial *serial,
177                                         speed_t value, speed_t *result)
178 {
179         *result = value;
180
181         if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
182                 || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
183                 switch (value) {
184                 case 300:
185                         return 0x01;
186                 case 600:
187                         return 0x02; /* this one not tested */
188                 case 1200:
189                         return 0x03;
190                 case 2400:
191                         return 0x04;
192                 case 4800:
193                         return 0x06;
194                 case 9600:
195                         return 0x08;
196                 case 19200:
197                         return 0x09;
198                 case 38400:
199                         return 0x0a;
200                 case 57600:
201                         return 0x0b;
202                 case 115200:
203                         return 0x0c;
204                 default:
205                         *result = 9600;
206                         return 0x08;
207                 }
208         } else {
209                 /* FIXME: Can we use any divider - should we do
210                    divider = 115200/value;
211                    real baud = 115200/divider */
212                 switch (value) {
213                 case 300: break;
214                 case 600: break;
215                 case 1200: break;
216                 case 2400: break;
217                 case 4800: break;
218                 case 9600: break;
219                 case 19200: break;
220                 case 38400: break;
221                 case 57600: break;
222                 case 115200: break;
223                 default:
224                         value = 9600;
225                         *result = 9600;
226                 }
227                 return 115200/value;
228         }
229 }
230
231 static int mct_u232_set_baud_rate(struct tty_struct *tty,
232         struct usb_serial *serial, struct usb_serial_port *port, speed_t value)
233 {
234         __le32 divisor;
235         int rc;
236         unsigned char zero_byte = 0;
237         unsigned char cts_enable_byte = 0;
238         speed_t speed;
239
240         divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value,
241                                                                 &speed));
242
243         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
244                                 MCT_U232_SET_BAUD_RATE_REQUEST,
245                                 MCT_U232_SET_REQUEST_TYPE,
246                                 0, 0, &divisor, MCT_U232_SET_BAUD_RATE_SIZE,
247                                 WDR_TIMEOUT);
248         if (rc < 0)     /*FIXME: What value speed results */
249                 err("Set BAUD RATE %d failed (error = %d)", value, rc);
250         else
251                 tty_encode_baud_rate(tty, speed, speed);
252         dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor);
253
254         /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
255            always sends two extra USB 'device request' messages after the
256            'baud rate change' message.  The actual functionality of the
257            request codes in these messages is not fully understood but these
258            particular codes are never seen in any operation besides a baud
259            rate change.  Both of these messages send a single byte of data.
260            In the first message, the value of this byte is always zero.
261
262            The second message has been determined experimentally to control
263            whether data will be transmitted to a device which is not asserting
264            the 'CTS' signal.  If the second message's data byte is zero, data
265            will be transmitted even if 'CTS' is not asserted (i.e. no hardware
266            flow control).  if the second message's data byte is nonzero (a
267            value of 1 is used by this driver), data will not be transmitted to
268            a device which is not asserting 'CTS'.
269         */
270
271         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
272                                 MCT_U232_SET_UNKNOWN1_REQUEST,
273                                 MCT_U232_SET_REQUEST_TYPE,
274                                 0, 0, &zero_byte, MCT_U232_SET_UNKNOWN1_SIZE,
275                                 WDR_TIMEOUT);
276         if (rc < 0)
277                 err("Sending USB device request code %d failed (error = %d)",
278                     MCT_U232_SET_UNKNOWN1_REQUEST, rc);
279
280         if (port && C_CRTSCTS(tty))
281            cts_enable_byte = 1;
282
283         dbg("set_baud_rate: send second control message, data = %02X",
284                                                         cts_enable_byte);
285         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
286                         MCT_U232_SET_CTS_REQUEST,
287                         MCT_U232_SET_REQUEST_TYPE,
288                         0, 0, &cts_enable_byte, MCT_U232_SET_CTS_SIZE,
289                         WDR_TIMEOUT);
290         if (rc < 0)
291                 err("Sending USB device request code %d failed (error = %d)",
292                                         MCT_U232_SET_CTS_REQUEST, rc);
293
294         return rc;
295 } /* mct_u232_set_baud_rate */
296
297 static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr)
298 {
299         int rc;
300         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
301                         MCT_U232_SET_LINE_CTRL_REQUEST,
302                         MCT_U232_SET_REQUEST_TYPE,
303                         0, 0, &lcr, MCT_U232_SET_LINE_CTRL_SIZE,
304                         WDR_TIMEOUT);
305         if (rc < 0)
306                 err("Set LINE CTRL 0x%x failed (error = %d)", lcr, rc);
307         dbg("set_line_ctrl: 0x%x", lcr);
308         return rc;
309 } /* mct_u232_set_line_ctrl */
310
311 static int mct_u232_set_modem_ctrl(struct usb_serial *serial,
312                                    unsigned int control_state)
313 {
314         int rc;
315         unsigned char mcr = MCT_U232_MCR_NONE;
316
317         if (control_state & TIOCM_DTR)
318                 mcr |= MCT_U232_MCR_DTR;
319         if (control_state & TIOCM_RTS)
320                 mcr |= MCT_U232_MCR_RTS;
321
322         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
323                         MCT_U232_SET_MODEM_CTRL_REQUEST,
324                         MCT_U232_SET_REQUEST_TYPE,
325                         0, 0, &mcr, MCT_U232_SET_MODEM_CTRL_SIZE,
326                         WDR_TIMEOUT);
327         if (rc < 0)
328                 err("Set MODEM CTRL 0x%x failed (error = %d)", mcr, rc);
329         dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr);
330
331         return rc;
332 } /* mct_u232_set_modem_ctrl */
333
334 static int mct_u232_get_modem_stat(struct usb_serial *serial,
335                                                 unsigned char *msr)
336 {
337         int rc;
338         rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
339                         MCT_U232_GET_MODEM_STAT_REQUEST,
340                         MCT_U232_GET_REQUEST_TYPE,
341                         0, 0, msr, MCT_U232_GET_MODEM_STAT_SIZE,
342                         WDR_TIMEOUT);
343         if (rc < 0) {
344                 err("Get MODEM STATus failed (error = %d)", rc);
345                 *msr = 0;
346         }
347         dbg("get_modem_stat: 0x%x", *msr);
348         return rc;
349 } /* mct_u232_get_modem_stat */
350
351 static void mct_u232_msr_to_state(unsigned int *control_state,
352                                                 unsigned char msr)
353 {
354         /* Translate Control Line states */
355         if (msr & MCT_U232_MSR_DSR)
356                 *control_state |=  TIOCM_DSR;
357         else
358                 *control_state &= ~TIOCM_DSR;
359         if (msr & MCT_U232_MSR_CTS)
360                 *control_state |=  TIOCM_CTS;
361         else
362                 *control_state &= ~TIOCM_CTS;
363         if (msr & MCT_U232_MSR_RI)
364                 *control_state |=  TIOCM_RI;
365         else
366                 *control_state &= ~TIOCM_RI;
367         if (msr & MCT_U232_MSR_CD)
368                 *control_state |=  TIOCM_CD;
369         else
370                 *control_state &= ~TIOCM_CD;
371         dbg("msr_to_state: msr=0x%x ==> state=0x%x", msr, *control_state);
372 } /* mct_u232_msr_to_state */
373
374 /*
375  * Driver's tty interface functions
376  */
377
378 static int mct_u232_startup(struct usb_serial *serial)
379 {
380         struct mct_u232_private *priv;
381         struct usb_serial_port *port, *rport;
382
383         priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
384         if (!priv)
385                 return -ENOMEM;
386         spin_lock_init(&priv->lock);
387         usb_set_serial_port_data(serial->port[0], priv);
388
389         init_waitqueue_head(&serial->port[0]->write_wait);
390
391         /* Puh, that's dirty */
392         port = serial->port[0];
393         rport = serial->port[1];
394         /* No unlinking, it wasn't submitted yet. */
395         usb_free_urb(port->read_urb);
396         port->read_urb = rport->interrupt_in_urb;
397         rport->interrupt_in_urb = NULL;
398         port->read_urb->context = port;
399
400         return 0;
401 } /* mct_u232_startup */
402
403
404 static void mct_u232_shutdown(struct usb_serial *serial)
405 {
406         struct mct_u232_private *priv;
407         int i;
408
409         dbg("%s", __func__);
410
411         for (i = 0; i < serial->num_ports; ++i) {
412                 /* My special items, the standard routines free my urbs */
413                 priv = usb_get_serial_port_data(serial->port[i]);
414                 if (priv) {
415                         usb_set_serial_port_data(serial->port[i], NULL);
416                         kfree(priv);
417                 }
418         }
419 } /* mct_u232_shutdown */
420
421 static int  mct_u232_open(struct tty_struct *tty,
422                         struct usb_serial_port *port, struct file *filp)
423 {
424         struct usb_serial *serial = port->serial;
425         struct mct_u232_private *priv = usb_get_serial_port_data(port);
426         int retval = 0;
427         unsigned int control_state;
428         unsigned long flags;
429         unsigned char last_lcr;
430         unsigned char last_msr;
431
432         dbg("%s port %d", __func__, port->number);
433
434         /* Compensate for a hardware bug: although the Sitecom U232-P25
435          * device reports a maximum output packet size of 32 bytes,
436          * it seems to be able to accept only 16 bytes (and that's what
437          * SniffUSB says too...)
438          */
439         if (le16_to_cpu(serial->dev->descriptor.idProduct)
440                                                 == MCT_U232_SITECOM_PID)
441                 port->bulk_out_size = 16;
442
443         /* Do a defined restart: the normal serial device seems to
444          * always turn on DTR and RTS here, so do the same. I'm not
445          * sure if this is really necessary. But it should not harm
446          * either.
447          */
448         spin_lock_irqsave(&priv->lock, flags);
449         if (tty && (tty->termios->c_cflag & CBAUD))
450                 priv->control_state = TIOCM_DTR | TIOCM_RTS;
451         else
452                 priv->control_state = 0;
453
454         priv->last_lcr = (MCT_U232_DATA_BITS_8 |
455                           MCT_U232_PARITY_NONE |
456                           MCT_U232_STOP_BITS_1);
457         control_state = priv->control_state;
458         last_lcr = priv->last_lcr;
459         spin_unlock_irqrestore(&priv->lock, flags);
460         mct_u232_set_modem_ctrl(serial, control_state);
461         mct_u232_set_line_ctrl(serial, last_lcr);
462
463         /* Read modem status and update control state */
464         mct_u232_get_modem_stat(serial, &last_msr);
465         spin_lock_irqsave(&priv->lock, flags);
466         priv->last_msr = last_msr;
467         mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
468         spin_unlock_irqrestore(&priv->lock, flags);
469
470         port->read_urb->dev = port->serial->dev;
471         retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
472         if (retval) {
473                 err("usb_submit_urb(read bulk) failed pipe 0x%x err %d",
474                     port->read_urb->pipe, retval);
475                 goto error;
476         }
477
478         port->interrupt_in_urb->dev = port->serial->dev;
479         retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
480         if (retval) {
481                 usb_kill_urb(port->read_urb);
482                 err(" usb_submit_urb(read int) failed pipe 0x%x err %d",
483                     port->interrupt_in_urb->pipe, retval);
484                 goto error;
485         }
486         return 0;
487
488 error:
489         return retval;
490 } /* mct_u232_open */
491
492
493 static void mct_u232_close(struct tty_struct *tty,
494                         struct usb_serial_port *port, struct file *filp)
495 {
496         unsigned int c_cflag;
497         unsigned int control_state;
498         struct mct_u232_private *priv = usb_get_serial_port_data(port);
499         dbg("%s port %d", __func__, port->number);
500
501         if (tty) {
502                 c_cflag = tty->termios->c_cflag;
503                 mutex_lock(&port->serial->disc_mutex);
504                 if (c_cflag & HUPCL && !port->serial->disconnected) {
505                         /* drop DTR and RTS */
506                         spin_lock_irq(&priv->lock);
507                         priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
508                         control_state = priv->control_state;
509                         spin_unlock_irq(&priv->lock);
510                         mct_u232_set_modem_ctrl(port->serial, control_state);
511                 }
512                 mutex_unlock(&port->serial->disc_mutex);
513         }
514
515
516         if (port->serial->dev) {
517                 /* shutdown our urbs */
518                 usb_kill_urb(port->write_urb);
519                 usb_kill_urb(port->read_urb);
520                 usb_kill_urb(port->interrupt_in_urb);
521         }
522 } /* mct_u232_close */
523
524
525 static void mct_u232_read_int_callback(struct urb *urb)
526 {
527         struct usb_serial_port *port = urb->context;
528         struct mct_u232_private *priv = usb_get_serial_port_data(port);
529         struct usb_serial *serial = port->serial;
530         struct tty_struct *tty;
531         unsigned char *data = urb->transfer_buffer;
532         int retval;
533         int status = urb->status;
534         unsigned long flags;
535
536         switch (status) {
537         case 0:
538                 /* success */
539                 break;
540         case -ECONNRESET:
541         case -ENOENT:
542         case -ESHUTDOWN:
543                 /* this urb is terminated, clean up */
544                 dbg("%s - urb shutting down with status: %d",
545                     __func__, status);
546                 return;
547         default:
548                 dbg("%s - nonzero urb status received: %d",
549                     __func__, status);
550                 goto exit;
551         }
552
553         if (!serial) {
554                 dbg("%s - bad serial pointer, exiting", __func__);
555                 return;
556         }
557
558         dbg("%s - port %d", __func__, port->number);
559         usb_serial_debug_data(debug, &port->dev, __func__,
560                                         urb->actual_length, data);
561
562         /*
563          * Work-a-round: handle the 'usual' bulk-in pipe here
564          */
565         if (urb->transfer_buffer_length > 2) {
566                 tty = port->port.tty;
567                 if (urb->actual_length) {
568                         tty_insert_flip_string(tty, data, urb->actual_length);
569                         tty_flip_buffer_push(tty);
570                 }
571                 goto exit;
572         }
573
574         /*
575          * The interrupt-in pipe signals exceptional conditions (modem line
576          * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
577          */
578         spin_lock_irqsave(&priv->lock, flags);
579         priv->last_msr = data[MCT_U232_MSR_INDEX];
580
581         /* Record Control Line states */
582         mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
583
584 #if 0
585         /* Not yet handled. See belkin_sa.c for further information */
586         /* Now to report any errors */
587         priv->last_lsr = data[MCT_U232_LSR_INDEX];
588         /*
589          * fill in the flip buffer here, but I do not know the relation
590          * to the current/next receive buffer or characters.  I need
591          * to look in to this before committing any code.
592          */
593         if (priv->last_lsr & MCT_U232_LSR_ERR) {
594                 tty = port->port.tty;
595                 /* Overrun Error */
596                 if (priv->last_lsr & MCT_U232_LSR_OE) {
597                 }
598                 /* Parity Error */
599                 if (priv->last_lsr & MCT_U232_LSR_PE) {
600                 }
601                 /* Framing Error */
602                 if (priv->last_lsr & MCT_U232_LSR_FE) {
603                 }
604                 /* Break Indicator */
605                 if (priv->last_lsr & MCT_U232_LSR_BI) {
606                 }
607         }
608 #endif
609         spin_unlock_irqrestore(&priv->lock, flags);
610 exit:
611         retval = usb_submit_urb(urb, GFP_ATOMIC);
612         if (retval)
613                 err("%s - usb_submit_urb failed with result %d",
614                      __func__, retval);
615 } /* mct_u232_read_int_callback */
616
617 static void mct_u232_set_termios(struct tty_struct *tty,
618                                  struct usb_serial_port *port,
619                                  struct ktermios *old_termios)
620 {
621         struct usb_serial *serial = port->serial;
622         struct mct_u232_private *priv = usb_get_serial_port_data(port);
623         struct ktermios *termios = tty->termios;
624         unsigned int cflag = termios->c_cflag;
625         unsigned int old_cflag = old_termios->c_cflag;
626         unsigned long flags;
627         unsigned int control_state;
628         unsigned char last_lcr;
629
630         /* get a local copy of the current port settings */
631         spin_lock_irqsave(&priv->lock, flags);
632         control_state = priv->control_state;
633         spin_unlock_irqrestore(&priv->lock, flags);
634         last_lcr = 0;
635
636         /*
637          * Update baud rate.
638          * Do not attempt to cache old rates and skip settings,
639          * disconnects screw such tricks up completely.
640          * Premature optimization is the root of all evil.
641          */
642
643         /* reassert DTR and RTS on transition from B0 */
644         if ((old_cflag & CBAUD) == B0) {
645                 dbg("%s: baud was B0", __func__);
646                 control_state |= TIOCM_DTR | TIOCM_RTS;
647                 mct_u232_set_modem_ctrl(serial, control_state);
648         }
649
650         mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty));
651
652         if ((cflag & CBAUD) == B0) {
653                 dbg("%s: baud is B0", __func__);
654                 /* Drop RTS and DTR */
655                 control_state &= ~(TIOCM_DTR | TIOCM_RTS);
656                 mct_u232_set_modem_ctrl(serial, control_state);
657         }
658
659         /*
660          * Update line control register (LCR)
661          */
662
663         /* set the parity */
664         if (cflag & PARENB)
665                 last_lcr |= (cflag & PARODD) ?
666                         MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
667         else
668                 last_lcr |= MCT_U232_PARITY_NONE;
669
670         /* set the number of data bits */
671         switch (cflag & CSIZE) {
672         case CS5:
673                 last_lcr |= MCT_U232_DATA_BITS_5; break;
674         case CS6:
675                 last_lcr |= MCT_U232_DATA_BITS_6; break;
676         case CS7:
677                 last_lcr |= MCT_U232_DATA_BITS_7; break;
678         case CS8:
679                 last_lcr |= MCT_U232_DATA_BITS_8; break;
680         default:
681                 err("CSIZE was not CS5-CS8, using default of 8");
682                 last_lcr |= MCT_U232_DATA_BITS_8;
683                 break;
684         }
685
686         termios->c_cflag &= ~CMSPAR;
687
688         /* set the number of stop bits */
689         last_lcr |= (cflag & CSTOPB) ?
690                 MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
691
692         mct_u232_set_line_ctrl(serial, last_lcr);
693
694         /* save off the modified port settings */
695         spin_lock_irqsave(&priv->lock, flags);
696         priv->control_state = control_state;
697         priv->last_lcr = last_lcr;
698         spin_unlock_irqrestore(&priv->lock, flags);
699 } /* mct_u232_set_termios */
700
701 static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
702 {
703         struct usb_serial_port *port = tty->driver_data;
704         struct usb_serial *serial = port->serial;
705         struct mct_u232_private *priv = usb_get_serial_port_data(port);
706         unsigned char lcr;
707         unsigned long flags;
708
709         dbg("%sstate=%d", __func__, break_state);
710
711         spin_lock_irqsave(&priv->lock, flags);
712         lcr = priv->last_lcr;
713         spin_unlock_irqrestore(&priv->lock, flags);
714
715         if (break_state)
716                 lcr |= MCT_U232_SET_BREAK;
717
718         mct_u232_set_line_ctrl(serial, lcr);
719 } /* mct_u232_break_ctl */
720
721
722 static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file)
723 {
724         struct usb_serial_port *port = tty->driver_data;
725         struct mct_u232_private *priv = usb_get_serial_port_data(port);
726         unsigned int control_state;
727         unsigned long flags;
728
729         dbg("%s", __func__);
730
731         spin_lock_irqsave(&priv->lock, flags);
732         control_state = priv->control_state;
733         spin_unlock_irqrestore(&priv->lock, flags);
734
735         return control_state;
736 }
737
738 static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file,
739                               unsigned int set, unsigned int clear)
740 {
741         struct usb_serial_port *port = tty->driver_data;
742         struct usb_serial *serial = port->serial;
743         struct mct_u232_private *priv = usb_get_serial_port_data(port);
744         unsigned int control_state;
745         unsigned long flags;
746
747         dbg("%s", __func__);
748
749         spin_lock_irqsave(&priv->lock, flags);
750         control_state = priv->control_state;
751
752         if (set & TIOCM_RTS)
753                 control_state |= TIOCM_RTS;
754         if (set & TIOCM_DTR)
755                 control_state |= TIOCM_DTR;
756         if (clear & TIOCM_RTS)
757                 control_state &= ~TIOCM_RTS;
758         if (clear & TIOCM_DTR)
759                 control_state &= ~TIOCM_DTR;
760
761         priv->control_state = control_state;
762         spin_unlock_irqrestore(&priv->lock, flags);
763         return mct_u232_set_modem_ctrl(serial, control_state);
764 }
765
766 static void mct_u232_throttle(struct tty_struct *tty)
767 {
768         struct usb_serial_port *port = tty->driver_data;
769         struct mct_u232_private *priv = usb_get_serial_port_data(port);
770         unsigned long flags;
771         unsigned int control_state;
772
773         dbg("%s - port %d", __func__, port->number);
774
775         spin_lock_irqsave(&priv->lock, flags);
776         priv->rx_flags |= THROTTLED;
777         if (C_CRTSCTS(tty)) {
778                 priv->control_state &= ~TIOCM_RTS;
779                 control_state = priv->control_state;
780                 spin_unlock_irqrestore(&priv->lock, flags);
781                 (void) mct_u232_set_modem_ctrl(port->serial, control_state);
782         } else {
783                 spin_unlock_irqrestore(&priv->lock, flags);
784         }
785 }
786
787
788 static void mct_u232_unthrottle(struct tty_struct *tty)
789 {
790         struct usb_serial_port *port = tty->driver_data;
791         struct mct_u232_private *priv = usb_get_serial_port_data(port);
792         unsigned long flags;
793         unsigned int control_state;
794
795         dbg("%s - port %d", __func__, port->number);
796
797         spin_lock_irqsave(&priv->lock, flags);
798         if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
799                 priv->rx_flags &= ~THROTTLED;
800                 priv->control_state |= TIOCM_RTS;
801                 control_state = priv->control_state;
802                 spin_unlock_irqrestore(&priv->lock, flags);
803                 (void) mct_u232_set_modem_ctrl(port->serial, control_state);
804         } else {
805                 spin_unlock_irqrestore(&priv->lock, flags);
806         }
807 }
808
809 static int __init mct_u232_init(void)
810 {
811         int retval;
812         retval = usb_serial_register(&mct_u232_device);
813         if (retval)
814                 goto failed_usb_serial_register;
815         retval = usb_register(&mct_u232_driver);
816         if (retval)
817                 goto failed_usb_register;
818         info(DRIVER_DESC " " DRIVER_VERSION);
819         return 0;
820 failed_usb_register:
821         usb_serial_deregister(&mct_u232_device);
822 failed_usb_serial_register:
823         return retval;
824 }
825
826
827 static void __exit mct_u232_exit(void)
828 {
829         usb_deregister(&mct_u232_driver);
830         usb_serial_deregister(&mct_u232_device);
831 }
832
833 module_init(mct_u232_init);
834 module_exit(mct_u232_exit);
835
836 MODULE_AUTHOR(DRIVER_AUTHOR);
837 MODULE_DESCRIPTION(DRIVER_DESC);
838 MODULE_LICENSE("GPL");
839
840 module_param(debug, bool, S_IRUGO | S_IWUSR);
841 MODULE_PARM_DESC(debug, "Debug enabled or not");