tty: usb-serial krefs
[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 = tty_port_tty_get(&port->port);
567                 if (urb->actual_length) {
568                         tty_insert_flip_string(tty, data, urb->actual_length);
569                         tty_flip_buffer_push(tty);
570                         tty_kref_put(tty);
571                 }
572                 goto exit;
573         }
574
575         /*
576          * The interrupt-in pipe signals exceptional conditions (modem line
577          * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
578          */
579         spin_lock_irqsave(&priv->lock, flags);
580         priv->last_msr = data[MCT_U232_MSR_INDEX];
581
582         /* Record Control Line states */
583         mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
584
585 #if 0
586         /* Not yet handled. See belkin_sa.c for further information */
587         /* Now to report any errors */
588         priv->last_lsr = data[MCT_U232_LSR_INDEX];
589         /*
590          * fill in the flip buffer here, but I do not know the relation
591          * to the current/next receive buffer or characters.  I need
592          * to look in to this before committing any code.
593          */
594         if (priv->last_lsr & MCT_U232_LSR_ERR) {
595                 tty = tty_port_tty_get(&port->port);
596                 /* Overrun Error */
597                 if (priv->last_lsr & MCT_U232_LSR_OE) {
598                 }
599                 /* Parity Error */
600                 if (priv->last_lsr & MCT_U232_LSR_PE) {
601                 }
602                 /* Framing Error */
603                 if (priv->last_lsr & MCT_U232_LSR_FE) {
604                 }
605                 /* Break Indicator */
606                 if (priv->last_lsr & MCT_U232_LSR_BI) {
607                 }
608                 tty_kref_put(tty);
609         }
610 #endif
611         spin_unlock_irqrestore(&priv->lock, flags);
612 exit:
613         retval = usb_submit_urb(urb, GFP_ATOMIC);
614         if (retval)
615                 err("%s - usb_submit_urb failed with result %d",
616                      __func__, retval);
617 } /* mct_u232_read_int_callback */
618
619 static void mct_u232_set_termios(struct tty_struct *tty,
620                                  struct usb_serial_port *port,
621                                  struct ktermios *old_termios)
622 {
623         struct usb_serial *serial = port->serial;
624         struct mct_u232_private *priv = usb_get_serial_port_data(port);
625         struct ktermios *termios = tty->termios;
626         unsigned int cflag = termios->c_cflag;
627         unsigned int old_cflag = old_termios->c_cflag;
628         unsigned long flags;
629         unsigned int control_state;
630         unsigned char last_lcr;
631
632         /* get a local copy of the current port settings */
633         spin_lock_irqsave(&priv->lock, flags);
634         control_state = priv->control_state;
635         spin_unlock_irqrestore(&priv->lock, flags);
636         last_lcr = 0;
637
638         /*
639          * Update baud rate.
640          * Do not attempt to cache old rates and skip settings,
641          * disconnects screw such tricks up completely.
642          * Premature optimization is the root of all evil.
643          */
644
645         /* reassert DTR and RTS on transition from B0 */
646         if ((old_cflag & CBAUD) == B0) {
647                 dbg("%s: baud was B0", __func__);
648                 control_state |= TIOCM_DTR | TIOCM_RTS;
649                 mct_u232_set_modem_ctrl(serial, control_state);
650         }
651
652         mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty));
653
654         if ((cflag & CBAUD) == B0) {
655                 dbg("%s: baud is B0", __func__);
656                 /* Drop RTS and DTR */
657                 control_state &= ~(TIOCM_DTR | TIOCM_RTS);
658                 mct_u232_set_modem_ctrl(serial, control_state);
659         }
660
661         /*
662          * Update line control register (LCR)
663          */
664
665         /* set the parity */
666         if (cflag & PARENB)
667                 last_lcr |= (cflag & PARODD) ?
668                         MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
669         else
670                 last_lcr |= MCT_U232_PARITY_NONE;
671
672         /* set the number of data bits */
673         switch (cflag & CSIZE) {
674         case CS5:
675                 last_lcr |= MCT_U232_DATA_BITS_5; break;
676         case CS6:
677                 last_lcr |= MCT_U232_DATA_BITS_6; break;
678         case CS7:
679                 last_lcr |= MCT_U232_DATA_BITS_7; break;
680         case CS8:
681                 last_lcr |= MCT_U232_DATA_BITS_8; break;
682         default:
683                 err("CSIZE was not CS5-CS8, using default of 8");
684                 last_lcr |= MCT_U232_DATA_BITS_8;
685                 break;
686         }
687
688         termios->c_cflag &= ~CMSPAR;
689
690         /* set the number of stop bits */
691         last_lcr |= (cflag & CSTOPB) ?
692                 MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
693
694         mct_u232_set_line_ctrl(serial, last_lcr);
695
696         /* save off the modified port settings */
697         spin_lock_irqsave(&priv->lock, flags);
698         priv->control_state = control_state;
699         priv->last_lcr = last_lcr;
700         spin_unlock_irqrestore(&priv->lock, flags);
701 } /* mct_u232_set_termios */
702
703 static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
704 {
705         struct usb_serial_port *port = tty->driver_data;
706         struct usb_serial *serial = port->serial;
707         struct mct_u232_private *priv = usb_get_serial_port_data(port);
708         unsigned char lcr;
709         unsigned long flags;
710
711         dbg("%sstate=%d", __func__, break_state);
712
713         spin_lock_irqsave(&priv->lock, flags);
714         lcr = priv->last_lcr;
715         spin_unlock_irqrestore(&priv->lock, flags);
716
717         if (break_state)
718                 lcr |= MCT_U232_SET_BREAK;
719
720         mct_u232_set_line_ctrl(serial, lcr);
721 } /* mct_u232_break_ctl */
722
723
724 static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file)
725 {
726         struct usb_serial_port *port = tty->driver_data;
727         struct mct_u232_private *priv = usb_get_serial_port_data(port);
728         unsigned int control_state;
729         unsigned long flags;
730
731         dbg("%s", __func__);
732
733         spin_lock_irqsave(&priv->lock, flags);
734         control_state = priv->control_state;
735         spin_unlock_irqrestore(&priv->lock, flags);
736
737         return control_state;
738 }
739
740 static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file,
741                               unsigned int set, unsigned int clear)
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 int control_state;
747         unsigned long flags;
748
749         dbg("%s", __func__);
750
751         spin_lock_irqsave(&priv->lock, flags);
752         control_state = priv->control_state;
753
754         if (set & TIOCM_RTS)
755                 control_state |= TIOCM_RTS;
756         if (set & TIOCM_DTR)
757                 control_state |= TIOCM_DTR;
758         if (clear & TIOCM_RTS)
759                 control_state &= ~TIOCM_RTS;
760         if (clear & TIOCM_DTR)
761                 control_state &= ~TIOCM_DTR;
762
763         priv->control_state = control_state;
764         spin_unlock_irqrestore(&priv->lock, flags);
765         return mct_u232_set_modem_ctrl(serial, control_state);
766 }
767
768 static void mct_u232_throttle(struct tty_struct *tty)
769 {
770         struct usb_serial_port *port = tty->driver_data;
771         struct mct_u232_private *priv = usb_get_serial_port_data(port);
772         unsigned long flags;
773         unsigned int control_state;
774
775         dbg("%s - port %d", __func__, port->number);
776
777         spin_lock_irqsave(&priv->lock, flags);
778         priv->rx_flags |= THROTTLED;
779         if (C_CRTSCTS(tty)) {
780                 priv->control_state &= ~TIOCM_RTS;
781                 control_state = priv->control_state;
782                 spin_unlock_irqrestore(&priv->lock, flags);
783                 (void) mct_u232_set_modem_ctrl(port->serial, control_state);
784         } else {
785                 spin_unlock_irqrestore(&priv->lock, flags);
786         }
787 }
788
789
790 static void mct_u232_unthrottle(struct tty_struct *tty)
791 {
792         struct usb_serial_port *port = tty->driver_data;
793         struct mct_u232_private *priv = usb_get_serial_port_data(port);
794         unsigned long flags;
795         unsigned int control_state;
796
797         dbg("%s - port %d", __func__, port->number);
798
799         spin_lock_irqsave(&priv->lock, flags);
800         if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
801                 priv->rx_flags &= ~THROTTLED;
802                 priv->control_state |= TIOCM_RTS;
803                 control_state = priv->control_state;
804                 spin_unlock_irqrestore(&priv->lock, flags);
805                 (void) mct_u232_set_modem_ctrl(port->serial, control_state);
806         } else {
807                 spin_unlock_irqrestore(&priv->lock, flags);
808         }
809 }
810
811 static int __init mct_u232_init(void)
812 {
813         int retval;
814         retval = usb_serial_register(&mct_u232_device);
815         if (retval)
816                 goto failed_usb_serial_register;
817         retval = usb_register(&mct_u232_driver);
818         if (retval)
819                 goto failed_usb_register;
820         info(DRIVER_DESC " " DRIVER_VERSION);
821         return 0;
822 failed_usb_register:
823         usb_serial_deregister(&mct_u232_device);
824 failed_usb_serial_register:
825         return retval;
826 }
827
828
829 static void __exit mct_u232_exit(void)
830 {
831         usb_deregister(&mct_u232_driver);
832         usb_serial_deregister(&mct_u232_device);
833 }
834
835 module_init(mct_u232_init);
836 module_exit(mct_u232_exit);
837
838 MODULE_AUTHOR(DRIVER_AUTHOR);
839 MODULE_DESCRIPTION(DRIVER_DESC);
840 MODULE_LICENSE("GPL");
841
842 module_param(debug, bool, S_IRUGO | S_IWUSR);
843 MODULE_PARM_DESC(debug, "Debug enabled or not");