2 * MCT (Magic Control Technology Corp.) USB RS232 Converter Driver
4 * Copyright (C) 2000 Wolfgang Grandegger (wolfgang@ces.ch)
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.
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.
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.
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.
24 #include <linux/kernel.h>
25 #include <linux/errno.h>
26 #include <linux/init.h>
27 #include <linux/slab.h>
28 #include <linux/tty.h>
29 #include <linux/tty_driver.h>
30 #include <linux/tty_flip.h>
31 #include <linux/module.h>
32 #include <linux/spinlock.h>
33 #include <linux/uaccess.h>
34 #include <asm/unaligned.h>
35 #include <linux/usb.h>
36 #include <linux/usb/serial.h>
37 #include <linux/serial.h>
40 #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
41 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
46 static int mct_u232_port_probe(struct usb_serial_port
*port
);
47 static int mct_u232_port_remove(struct usb_serial_port
*remove
);
48 static int mct_u232_open(struct tty_struct
*tty
, struct usb_serial_port
*port
);
49 static void mct_u232_close(struct usb_serial_port
*port
);
50 static void mct_u232_dtr_rts(struct usb_serial_port
*port
, int on
);
51 static void mct_u232_read_int_callback(struct urb
*urb
);
52 static void mct_u232_set_termios(struct tty_struct
*tty
,
53 struct usb_serial_port
*port
, struct ktermios
*old
);
54 static void mct_u232_break_ctl(struct tty_struct
*tty
, int break_state
);
55 static int mct_u232_tiocmget(struct tty_struct
*tty
);
56 static int mct_u232_tiocmset(struct tty_struct
*tty
,
57 unsigned int set
, unsigned int clear
);
58 static void mct_u232_throttle(struct tty_struct
*tty
);
59 static void mct_u232_unthrottle(struct tty_struct
*tty
);
63 * All of the device info needed for the MCT USB-RS232 converter.
65 static const struct usb_device_id id_table
[] = {
66 { USB_DEVICE(MCT_U232_VID
, MCT_U232_PID
) },
67 { USB_DEVICE(MCT_U232_VID
, MCT_U232_SITECOM_PID
) },
68 { USB_DEVICE(MCT_U232_VID
, MCT_U232_DU_H3SP_PID
) },
69 { USB_DEVICE(MCT_U232_BELKIN_F5U109_VID
, MCT_U232_BELKIN_F5U109_PID
) },
70 { } /* Terminating entry */
72 MODULE_DEVICE_TABLE(usb
, id_table
);
74 static struct usb_serial_driver mct_u232_device
= {
79 .description
= "MCT U232",
82 .open
= mct_u232_open
,
83 .close
= mct_u232_close
,
84 .dtr_rts
= mct_u232_dtr_rts
,
85 .throttle
= mct_u232_throttle
,
86 .unthrottle
= mct_u232_unthrottle
,
87 .read_int_callback
= mct_u232_read_int_callback
,
88 .set_termios
= mct_u232_set_termios
,
89 .break_ctl
= mct_u232_break_ctl
,
90 .tiocmget
= mct_u232_tiocmget
,
91 .tiocmset
= mct_u232_tiocmset
,
92 .tiocmiwait
= usb_serial_generic_tiocmiwait
,
93 .port_probe
= mct_u232_port_probe
,
94 .port_remove
= mct_u232_port_remove
,
95 .get_icount
= usb_serial_generic_get_icount
,
98 static struct usb_serial_driver
* const serial_drivers
[] = {
99 &mct_u232_device
, NULL
102 struct mct_u232_private
{
103 struct urb
*read_urb
;
105 unsigned int control_state
; /* Modem Line Setting (TIOCM) */
106 unsigned char last_lcr
; /* Line Control Register */
107 unsigned char last_lsr
; /* Line Status Register */
108 unsigned char last_msr
; /* Modem Status Register */
109 unsigned int rx_flags
; /* Throttling flags */
112 #define THROTTLED 0x01
115 * Handle vendor specific USB requests
118 #define WDR_TIMEOUT 5000 /* default urb timeout */
121 * Later day 2.6.0-test kernels have new baud rates like B230400 which
122 * we do not know how to support. We ignore them for the moment.
124 static int mct_u232_calculate_baud_rate(struct usb_serial
*serial
,
125 speed_t value
, speed_t
*result
)
129 if (le16_to_cpu(serial
->dev
->descriptor
.idProduct
) == MCT_U232_SITECOM_PID
130 || le16_to_cpu(serial
->dev
->descriptor
.idProduct
) == MCT_U232_BELKIN_F5U109_PID
) {
135 return 0x02; /* this one not tested */
157 /* FIXME: Can we use any divider - should we do
158 divider = 115200/value;
159 real baud = 115200/divider */
179 static int mct_u232_set_baud_rate(struct tty_struct
*tty
,
180 struct usb_serial
*serial
, struct usb_serial_port
*port
, speed_t value
)
182 unsigned int divisor
;
185 unsigned char cts_enable_byte
= 0;
188 buf
= kmalloc(MCT_U232_MAX_SIZE
, GFP_KERNEL
);
192 divisor
= mct_u232_calculate_baud_rate(serial
, value
, &speed
);
193 put_unaligned_le32(cpu_to_le32(divisor
), buf
);
194 rc
= usb_control_msg(serial
->dev
, usb_sndctrlpipe(serial
->dev
, 0),
195 MCT_U232_SET_BAUD_RATE_REQUEST
,
196 MCT_U232_SET_REQUEST_TYPE
,
197 0, 0, buf
, MCT_U232_SET_BAUD_RATE_SIZE
,
199 if (rc
< 0) /*FIXME: What value speed results */
200 dev_err(&port
->dev
, "Set BAUD RATE %d failed (error = %d)\n",
203 tty_encode_baud_rate(tty
, speed
, speed
);
204 dev_dbg(&port
->dev
, "set_baud_rate: value: 0x%x, divisor: 0x%x\n", value
, divisor
);
206 /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
207 always sends two extra USB 'device request' messages after the
208 'baud rate change' message. The actual functionality of the
209 request codes in these messages is not fully understood but these
210 particular codes are never seen in any operation besides a baud
211 rate change. Both of these messages send a single byte of data.
212 In the first message, the value of this byte is always zero.
214 The second message has been determined experimentally to control
215 whether data will be transmitted to a device which is not asserting
216 the 'CTS' signal. If the second message's data byte is zero, data
217 will be transmitted even if 'CTS' is not asserted (i.e. no hardware
218 flow control). if the second message's data byte is nonzero (a
219 value of 1 is used by this driver), data will not be transmitted to
220 a device which is not asserting 'CTS'.
224 rc
= usb_control_msg(serial
->dev
, usb_sndctrlpipe(serial
->dev
, 0),
225 MCT_U232_SET_UNKNOWN1_REQUEST
,
226 MCT_U232_SET_REQUEST_TYPE
,
227 0, 0, buf
, MCT_U232_SET_UNKNOWN1_SIZE
,
230 dev_err(&port
->dev
, "Sending USB device request code %d "
231 "failed (error = %d)\n", MCT_U232_SET_UNKNOWN1_REQUEST
,
234 if (port
&& C_CRTSCTS(tty
))
237 dev_dbg(&port
->dev
, "set_baud_rate: send second control message, data = %02X\n",
239 buf
[0] = cts_enable_byte
;
240 rc
= usb_control_msg(serial
->dev
, usb_sndctrlpipe(serial
->dev
, 0),
241 MCT_U232_SET_CTS_REQUEST
,
242 MCT_U232_SET_REQUEST_TYPE
,
243 0, 0, buf
, MCT_U232_SET_CTS_SIZE
,
246 dev_err(&port
->dev
, "Sending USB device request code %d "
247 "failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST
, rc
);
251 } /* mct_u232_set_baud_rate */
253 static int mct_u232_set_line_ctrl(struct usb_serial_port
*port
,
259 buf
= kmalloc(MCT_U232_MAX_SIZE
, GFP_KERNEL
);
264 rc
= usb_control_msg(port
->serial
->dev
, usb_sndctrlpipe(port
->serial
->dev
, 0),
265 MCT_U232_SET_LINE_CTRL_REQUEST
,
266 MCT_U232_SET_REQUEST_TYPE
,
267 0, 0, buf
, MCT_U232_SET_LINE_CTRL_SIZE
,
270 dev_err(&port
->dev
, "Set LINE CTRL 0x%x failed (error = %d)\n", lcr
, rc
);
271 dev_dbg(&port
->dev
, "set_line_ctrl: 0x%x\n", lcr
);
274 } /* mct_u232_set_line_ctrl */
276 static int mct_u232_set_modem_ctrl(struct usb_serial_port
*port
,
277 unsigned int control_state
)
283 buf
= kmalloc(MCT_U232_MAX_SIZE
, GFP_KERNEL
);
287 mcr
= MCT_U232_MCR_NONE
;
288 if (control_state
& TIOCM_DTR
)
289 mcr
|= MCT_U232_MCR_DTR
;
290 if (control_state
& TIOCM_RTS
)
291 mcr
|= MCT_U232_MCR_RTS
;
294 rc
= usb_control_msg(port
->serial
->dev
, usb_sndctrlpipe(port
->serial
->dev
, 0),
295 MCT_U232_SET_MODEM_CTRL_REQUEST
,
296 MCT_U232_SET_REQUEST_TYPE
,
297 0, 0, buf
, MCT_U232_SET_MODEM_CTRL_SIZE
,
301 dev_dbg(&port
->dev
, "set_modem_ctrl: state=0x%x ==> mcr=0x%x\n", control_state
, mcr
);
304 dev_err(&port
->dev
, "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr
, rc
);
308 } /* mct_u232_set_modem_ctrl */
310 static int mct_u232_get_modem_stat(struct usb_serial_port
*port
,
316 buf
= kmalloc(MCT_U232_MAX_SIZE
, GFP_KERNEL
);
321 rc
= usb_control_msg(port
->serial
->dev
, usb_rcvctrlpipe(port
->serial
->dev
, 0),
322 MCT_U232_GET_MODEM_STAT_REQUEST
,
323 MCT_U232_GET_REQUEST_TYPE
,
324 0, 0, buf
, MCT_U232_GET_MODEM_STAT_SIZE
,
327 dev_err(&port
->dev
, "Get MODEM STATus failed (error = %d)\n", rc
);
332 dev_dbg(&port
->dev
, "get_modem_stat: 0x%x\n", *msr
);
335 } /* mct_u232_get_modem_stat */
337 static void mct_u232_msr_to_icount(struct async_icount
*icount
,
340 /* Translate Control Line states */
341 if (msr
& MCT_U232_MSR_DDSR
)
343 if (msr
& MCT_U232_MSR_DCTS
)
345 if (msr
& MCT_U232_MSR_DRI
)
347 if (msr
& MCT_U232_MSR_DCD
)
349 } /* mct_u232_msr_to_icount */
351 static void mct_u232_msr_to_state(struct usb_serial_port
*port
,
352 unsigned int *control_state
, unsigned char msr
)
354 /* Translate Control Line states */
355 if (msr
& MCT_U232_MSR_DSR
)
356 *control_state
|= TIOCM_DSR
;
358 *control_state
&= ~TIOCM_DSR
;
359 if (msr
& MCT_U232_MSR_CTS
)
360 *control_state
|= TIOCM_CTS
;
362 *control_state
&= ~TIOCM_CTS
;
363 if (msr
& MCT_U232_MSR_RI
)
364 *control_state
|= TIOCM_RI
;
366 *control_state
&= ~TIOCM_RI
;
367 if (msr
& MCT_U232_MSR_CD
)
368 *control_state
|= TIOCM_CD
;
370 *control_state
&= ~TIOCM_CD
;
371 dev_dbg(&port
->dev
, "msr_to_state: msr=0x%x ==> state=0x%x\n", msr
, *control_state
);
372 } /* mct_u232_msr_to_state */
375 * Driver's tty interface functions
378 static int mct_u232_port_probe(struct usb_serial_port
*port
)
380 struct mct_u232_private
*priv
;
382 priv
= kzalloc(sizeof(*priv
), GFP_KERNEL
);
386 /* Use second interrupt-in endpoint for reading. */
387 priv
->read_urb
= port
->serial
->port
[1]->interrupt_in_urb
;
388 priv
->read_urb
->context
= port
;
390 spin_lock_init(&priv
->lock
);
392 usb_set_serial_port_data(port
, priv
);
397 static int mct_u232_port_remove(struct usb_serial_port
*port
)
399 struct mct_u232_private
*priv
;
401 priv
= usb_get_serial_port_data(port
);
407 static int mct_u232_open(struct tty_struct
*tty
, struct usb_serial_port
*port
)
409 struct usb_serial
*serial
= port
->serial
;
410 struct mct_u232_private
*priv
= usb_get_serial_port_data(port
);
412 unsigned int control_state
;
414 unsigned char last_lcr
;
415 unsigned char last_msr
;
417 /* Compensate for a hardware bug: although the Sitecom U232-P25
418 * device reports a maximum output packet size of 32 bytes,
419 * it seems to be able to accept only 16 bytes (and that's what
420 * SniffUSB says too...)
422 if (le16_to_cpu(serial
->dev
->descriptor
.idProduct
)
423 == MCT_U232_SITECOM_PID
)
424 port
->bulk_out_size
= 16;
426 /* Do a defined restart: the normal serial device seems to
427 * always turn on DTR and RTS here, so do the same. I'm not
428 * sure if this is really necessary. But it should not harm
431 spin_lock_irqsave(&priv
->lock
, flags
);
432 if (tty
&& (tty
->termios
.c_cflag
& CBAUD
))
433 priv
->control_state
= TIOCM_DTR
| TIOCM_RTS
;
435 priv
->control_state
= 0;
437 priv
->last_lcr
= (MCT_U232_DATA_BITS_8
|
438 MCT_U232_PARITY_NONE
|
439 MCT_U232_STOP_BITS_1
);
440 control_state
= priv
->control_state
;
441 last_lcr
= priv
->last_lcr
;
442 spin_unlock_irqrestore(&priv
->lock
, flags
);
443 mct_u232_set_modem_ctrl(port
, control_state
);
444 mct_u232_set_line_ctrl(port
, last_lcr
);
446 /* Read modem status and update control state */
447 mct_u232_get_modem_stat(port
, &last_msr
);
448 spin_lock_irqsave(&priv
->lock
, flags
);
449 priv
->last_msr
= last_msr
;
450 mct_u232_msr_to_state(port
, &priv
->control_state
, priv
->last_msr
);
451 spin_unlock_irqrestore(&priv
->lock
, flags
);
453 retval
= usb_submit_urb(priv
->read_urb
, GFP_KERNEL
);
456 "usb_submit_urb(read) failed pipe 0x%x err %d\n",
457 port
->read_urb
->pipe
, retval
);
461 retval
= usb_submit_urb(port
->interrupt_in_urb
, GFP_KERNEL
);
463 usb_kill_urb(priv
->read_urb
);
465 "usb_submit_urb(read int) failed pipe 0x%x err %d",
466 port
->interrupt_in_urb
->pipe
, retval
);
473 } /* mct_u232_open */
475 static void mct_u232_dtr_rts(struct usb_serial_port
*port
, int on
)
477 unsigned int control_state
;
478 struct mct_u232_private
*priv
= usb_get_serial_port_data(port
);
480 spin_lock_irq(&priv
->lock
);
482 priv
->control_state
|= TIOCM_DTR
| TIOCM_RTS
;
484 priv
->control_state
&= ~(TIOCM_DTR
| TIOCM_RTS
);
485 control_state
= priv
->control_state
;
486 spin_unlock_irq(&priv
->lock
);
488 mct_u232_set_modem_ctrl(port
, control_state
);
491 static void mct_u232_close(struct usb_serial_port
*port
)
493 struct mct_u232_private
*priv
= usb_get_serial_port_data(port
);
495 usb_kill_urb(priv
->read_urb
);
496 usb_kill_urb(port
->interrupt_in_urb
);
498 usb_serial_generic_close(port
);
499 } /* mct_u232_close */
502 static void mct_u232_read_int_callback(struct urb
*urb
)
504 struct usb_serial_port
*port
= urb
->context
;
505 struct mct_u232_private
*priv
= usb_get_serial_port_data(port
);
506 unsigned char *data
= urb
->transfer_buffer
;
508 int status
= urb
->status
;
518 /* this urb is terminated, clean up */
519 dev_dbg(&port
->dev
, "%s - urb shutting down with status: %d\n",
523 dev_dbg(&port
->dev
, "%s - nonzero urb status received: %d\n",
528 usb_serial_debug_data(&port
->dev
, __func__
, urb
->actual_length
, data
);
531 * Work-a-round: handle the 'usual' bulk-in pipe here
533 if (urb
->transfer_buffer_length
> 2) {
534 if (urb
->actual_length
) {
535 tty_insert_flip_string(&port
->port
, data
,
537 tty_flip_buffer_push(&port
->port
);
543 * The interrupt-in pipe signals exceptional conditions (modem line
544 * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
546 spin_lock_irqsave(&priv
->lock
, flags
);
547 priv
->last_msr
= data
[MCT_U232_MSR_INDEX
];
549 /* Record Control Line states */
550 mct_u232_msr_to_state(port
, &priv
->control_state
, priv
->last_msr
);
552 mct_u232_msr_to_icount(&port
->icount
, priv
->last_msr
);
555 /* Not yet handled. See belkin_sa.c for further information */
556 /* Now to report any errors */
557 priv
->last_lsr
= data
[MCT_U232_LSR_INDEX
];
559 * fill in the flip buffer here, but I do not know the relation
560 * to the current/next receive buffer or characters. I need
561 * to look in to this before committing any code.
563 if (priv
->last_lsr
& MCT_U232_LSR_ERR
) {
564 tty
= tty_port_tty_get(&port
->port
);
566 if (priv
->last_lsr
& MCT_U232_LSR_OE
) {
569 if (priv
->last_lsr
& MCT_U232_LSR_PE
) {
572 if (priv
->last_lsr
& MCT_U232_LSR_FE
) {
574 /* Break Indicator */
575 if (priv
->last_lsr
& MCT_U232_LSR_BI
) {
580 wake_up_interruptible(&port
->port
.delta_msr_wait
);
581 spin_unlock_irqrestore(&priv
->lock
, flags
);
583 retval
= usb_submit_urb(urb
, GFP_ATOMIC
);
586 "%s - usb_submit_urb failed with result %d\n",
588 } /* mct_u232_read_int_callback */
590 static void mct_u232_set_termios(struct tty_struct
*tty
,
591 struct usb_serial_port
*port
,
592 struct ktermios
*old_termios
)
594 struct usb_serial
*serial
= port
->serial
;
595 struct mct_u232_private
*priv
= usb_get_serial_port_data(port
);
596 struct ktermios
*termios
= &tty
->termios
;
597 unsigned int cflag
= termios
->c_cflag
;
598 unsigned int old_cflag
= old_termios
->c_cflag
;
600 unsigned int control_state
;
601 unsigned char last_lcr
;
603 /* get a local copy of the current port settings */
604 spin_lock_irqsave(&priv
->lock
, flags
);
605 control_state
= priv
->control_state
;
606 spin_unlock_irqrestore(&priv
->lock
, flags
);
611 * Do not attempt to cache old rates and skip settings,
612 * disconnects screw such tricks up completely.
613 * Premature optimization is the root of all evil.
616 /* reassert DTR and RTS on transition from B0 */
617 if ((old_cflag
& CBAUD
) == B0
) {
618 dev_dbg(&port
->dev
, "%s: baud was B0\n", __func__
);
619 control_state
|= TIOCM_DTR
| TIOCM_RTS
;
620 mct_u232_set_modem_ctrl(port
, control_state
);
623 mct_u232_set_baud_rate(tty
, serial
, port
, tty_get_baud_rate(tty
));
625 if ((cflag
& CBAUD
) == B0
) {
626 dev_dbg(&port
->dev
, "%s: baud is B0\n", __func__
);
627 /* Drop RTS and DTR */
628 control_state
&= ~(TIOCM_DTR
| TIOCM_RTS
);
629 mct_u232_set_modem_ctrl(port
, control_state
);
633 * Update line control register (LCR)
638 last_lcr
|= (cflag
& PARODD
) ?
639 MCT_U232_PARITY_ODD
: MCT_U232_PARITY_EVEN
;
641 last_lcr
|= MCT_U232_PARITY_NONE
;
643 /* set the number of data bits */
644 switch (cflag
& CSIZE
) {
646 last_lcr
|= MCT_U232_DATA_BITS_5
; break;
648 last_lcr
|= MCT_U232_DATA_BITS_6
; break;
650 last_lcr
|= MCT_U232_DATA_BITS_7
; break;
652 last_lcr
|= MCT_U232_DATA_BITS_8
; break;
655 "CSIZE was not CS5-CS8, using default of 8\n");
656 last_lcr
|= MCT_U232_DATA_BITS_8
;
660 termios
->c_cflag
&= ~CMSPAR
;
662 /* set the number of stop bits */
663 last_lcr
|= (cflag
& CSTOPB
) ?
664 MCT_U232_STOP_BITS_2
: MCT_U232_STOP_BITS_1
;
666 mct_u232_set_line_ctrl(port
, last_lcr
);
668 /* save off the modified port settings */
669 spin_lock_irqsave(&priv
->lock
, flags
);
670 priv
->control_state
= control_state
;
671 priv
->last_lcr
= last_lcr
;
672 spin_unlock_irqrestore(&priv
->lock
, flags
);
673 } /* mct_u232_set_termios */
675 static void mct_u232_break_ctl(struct tty_struct
*tty
, int break_state
)
677 struct usb_serial_port
*port
= tty
->driver_data
;
678 struct mct_u232_private
*priv
= usb_get_serial_port_data(port
);
682 spin_lock_irqsave(&priv
->lock
, flags
);
683 lcr
= priv
->last_lcr
;
686 lcr
|= MCT_U232_SET_BREAK
;
687 spin_unlock_irqrestore(&priv
->lock
, flags
);
689 mct_u232_set_line_ctrl(port
, lcr
);
690 } /* mct_u232_break_ctl */
693 static int mct_u232_tiocmget(struct tty_struct
*tty
)
695 struct usb_serial_port
*port
= tty
->driver_data
;
696 struct mct_u232_private
*priv
= usb_get_serial_port_data(port
);
697 unsigned int control_state
;
700 spin_lock_irqsave(&priv
->lock
, flags
);
701 control_state
= priv
->control_state
;
702 spin_unlock_irqrestore(&priv
->lock
, flags
);
704 return control_state
;
707 static int mct_u232_tiocmset(struct tty_struct
*tty
,
708 unsigned int set
, unsigned int clear
)
710 struct usb_serial_port
*port
= tty
->driver_data
;
711 struct mct_u232_private
*priv
= usb_get_serial_port_data(port
);
712 unsigned int control_state
;
715 spin_lock_irqsave(&priv
->lock
, flags
);
716 control_state
= priv
->control_state
;
719 control_state
|= TIOCM_RTS
;
721 control_state
|= TIOCM_DTR
;
722 if (clear
& TIOCM_RTS
)
723 control_state
&= ~TIOCM_RTS
;
724 if (clear
& TIOCM_DTR
)
725 control_state
&= ~TIOCM_DTR
;
727 priv
->control_state
= control_state
;
728 spin_unlock_irqrestore(&priv
->lock
, flags
);
729 return mct_u232_set_modem_ctrl(port
, control_state
);
732 static void mct_u232_throttle(struct tty_struct
*tty
)
734 struct usb_serial_port
*port
= tty
->driver_data
;
735 struct mct_u232_private
*priv
= usb_get_serial_port_data(port
);
736 unsigned int control_state
;
738 spin_lock_irq(&priv
->lock
);
739 priv
->rx_flags
|= THROTTLED
;
740 if (C_CRTSCTS(tty
)) {
741 priv
->control_state
&= ~TIOCM_RTS
;
742 control_state
= priv
->control_state
;
743 spin_unlock_irq(&priv
->lock
);
744 mct_u232_set_modem_ctrl(port
, control_state
);
746 spin_unlock_irq(&priv
->lock
);
750 static void mct_u232_unthrottle(struct tty_struct
*tty
)
752 struct usb_serial_port
*port
= tty
->driver_data
;
753 struct mct_u232_private
*priv
= usb_get_serial_port_data(port
);
754 unsigned int control_state
;
756 spin_lock_irq(&priv
->lock
);
757 if ((priv
->rx_flags
& THROTTLED
) && C_CRTSCTS(tty
)) {
758 priv
->rx_flags
&= ~THROTTLED
;
759 priv
->control_state
|= TIOCM_RTS
;
760 control_state
= priv
->control_state
;
761 spin_unlock_irq(&priv
->lock
);
762 mct_u232_set_modem_ctrl(port
, control_state
);
764 spin_unlock_irq(&priv
->lock
);
768 module_usb_serial_driver(serial_drivers
, id_table
);
770 MODULE_AUTHOR(DRIVER_AUTHOR
);
771 MODULE_DESCRIPTION(DRIVER_DESC
);
772 MODULE_LICENSE("GPL");