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>
38 #include <linux/ioctl.h>
44 #define DRIVER_VERSION "z2.1" /* Linux in-kernel version */
45 #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
46 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
51 static int mct_u232_startup(struct usb_serial *serial);
52 static void mct_u232_release(struct usb_serial *serial);
53 static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);
54 static void mct_u232_close(struct usb_serial_port *port);
55 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on);
56 static void mct_u232_read_int_callback(struct urb *urb);
57 static void mct_u232_set_termios(struct tty_struct *tty,
58 struct usb_serial_port *port, struct ktermios *old);
59 static void mct_u232_break_ctl(struct tty_struct *tty, int break_state);
60 static int mct_u232_tiocmget(struct tty_struct *tty);
61 static int mct_u232_tiocmset(struct tty_struct *tty,
62 unsigned int set, unsigned int clear);
63 static int mct_u232_ioctl(struct tty_struct *tty,
64 unsigned int cmd, unsigned long arg);
65 static int mct_u232_get_icount(struct tty_struct *tty,
66 struct serial_icounter_struct *icount);
67 static void mct_u232_throttle(struct tty_struct *tty);
68 static void mct_u232_unthrottle(struct tty_struct *tty);
72 * All of the device info needed for the MCT USB-RS232 converter.
74 static const struct usb_device_id id_table[] = {
75 { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
76 { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
77 { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
78 { USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },
79 { } /* Terminating entry */
81 MODULE_DEVICE_TABLE(usb, id_table);
83 static struct usb_serial_driver mct_u232_device = {
88 .description = "MCT U232",
91 .open = mct_u232_open,
92 .close = mct_u232_close,
93 .dtr_rts = mct_u232_dtr_rts,
94 .throttle = mct_u232_throttle,
95 .unthrottle = mct_u232_unthrottle,
96 .read_int_callback = mct_u232_read_int_callback,
97 .set_termios = mct_u232_set_termios,
98 .break_ctl = mct_u232_break_ctl,
99 .tiocmget = mct_u232_tiocmget,
100 .tiocmset = mct_u232_tiocmset,
101 .attach = mct_u232_startup,
102 .release = mct_u232_release,
103 .ioctl = mct_u232_ioctl,
104 .get_icount = mct_u232_get_icount,
107 static struct usb_serial_driver * const serial_drivers[] = {
108 &mct_u232_device, NULL
111 struct mct_u232_private {
113 unsigned int control_state; /* Modem Line Setting (TIOCM) */
114 unsigned char last_lcr; /* Line Control Register */
115 unsigned char last_lsr; /* Line Status Register */
116 unsigned char last_msr; /* Modem Status Register */
117 unsigned int rx_flags; /* Throttling flags */
118 struct async_icount icount;
119 wait_queue_head_t msr_wait; /* for handling sleeping while waiting
120 for msr change to happen */
123 #define THROTTLED 0x01
126 * Handle vendor specific USB requests
129 #define WDR_TIMEOUT 5000 /* default urb timeout */
132 * Later day 2.6.0-test kernels have new baud rates like B230400 which
133 * we do not know how to support. We ignore them for the moment.
135 static int mct_u232_calculate_baud_rate(struct usb_serial *serial,
136 speed_t value, speed_t *result)
140 if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
141 || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
146 return 0x02; /* this one not tested */
168 /* FIXME: Can we use any divider - should we do
169 divider = 115200/value;
170 real baud = 115200/divider */
190 static int mct_u232_set_baud_rate(struct tty_struct *tty,
191 struct usb_serial *serial, struct usb_serial_port *port, speed_t value)
193 unsigned int divisor;
196 unsigned char cts_enable_byte = 0;
199 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
203 divisor = mct_u232_calculate_baud_rate(serial, value, &speed);
204 put_unaligned_le32(cpu_to_le32(divisor), buf);
205 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
206 MCT_U232_SET_BAUD_RATE_REQUEST,
207 MCT_U232_SET_REQUEST_TYPE,
208 0, 0, buf, MCT_U232_SET_BAUD_RATE_SIZE,
210 if (rc < 0) /*FIXME: What value speed results */
211 dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n",
214 tty_encode_baud_rate(tty, speed, speed);
215 dev_dbg(&port->dev, "set_baud_rate: value: 0x%x, divisor: 0x%x\n", value, divisor);
217 /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
218 always sends two extra USB 'device request' messages after the
219 'baud rate change' message. The actual functionality of the
220 request codes in these messages is not fully understood but these
221 particular codes are never seen in any operation besides a baud
222 rate change. Both of these messages send a single byte of data.
223 In the first message, the value of this byte is always zero.
225 The second message has been determined experimentally to control
226 whether data will be transmitted to a device which is not asserting
227 the 'CTS' signal. If the second message's data byte is zero, data
228 will be transmitted even if 'CTS' is not asserted (i.e. no hardware
229 flow control). if the second message's data byte is nonzero (a
230 value of 1 is used by this driver), data will not be transmitted to
231 a device which is not asserting 'CTS'.
235 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
236 MCT_U232_SET_UNKNOWN1_REQUEST,
237 MCT_U232_SET_REQUEST_TYPE,
238 0, 0, buf, MCT_U232_SET_UNKNOWN1_SIZE,
241 dev_err(&port->dev, "Sending USB device request code %d "
242 "failed (error = %d)\n", MCT_U232_SET_UNKNOWN1_REQUEST,
245 if (port && C_CRTSCTS(tty))
248 dev_dbg(&port->dev, "set_baud_rate: send second control message, data = %02X\n",
250 buf[0] = cts_enable_byte;
251 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
252 MCT_U232_SET_CTS_REQUEST,
253 MCT_U232_SET_REQUEST_TYPE,
254 0, 0, buf, MCT_U232_SET_CTS_SIZE,
257 dev_err(&port->dev, "Sending USB device request code %d "
258 "failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc);
262 } /* mct_u232_set_baud_rate */
264 static int mct_u232_set_line_ctrl(struct usb_serial_port *port,
270 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
275 rc = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
276 MCT_U232_SET_LINE_CTRL_REQUEST,
277 MCT_U232_SET_REQUEST_TYPE,
278 0, 0, buf, MCT_U232_SET_LINE_CTRL_SIZE,
281 dev_err(&port->dev, "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc);
282 dev_dbg(&port->dev, "set_line_ctrl: 0x%x\n", lcr);
285 } /* mct_u232_set_line_ctrl */
287 static int mct_u232_set_modem_ctrl(struct usb_serial_port *port,
288 unsigned int control_state)
294 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
298 mcr = MCT_U232_MCR_NONE;
299 if (control_state & TIOCM_DTR)
300 mcr |= MCT_U232_MCR_DTR;
301 if (control_state & TIOCM_RTS)
302 mcr |= MCT_U232_MCR_RTS;
305 rc = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
306 MCT_U232_SET_MODEM_CTRL_REQUEST,
307 MCT_U232_SET_REQUEST_TYPE,
308 0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE,
312 dev_dbg(&port->dev, "set_modem_ctrl: state=0x%x ==> mcr=0x%x\n", control_state, mcr);
315 dev_err(&port->dev, "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc);
319 } /* mct_u232_set_modem_ctrl */
321 static int mct_u232_get_modem_stat(struct usb_serial_port *port,
327 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
332 rc = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0),
333 MCT_U232_GET_MODEM_STAT_REQUEST,
334 MCT_U232_GET_REQUEST_TYPE,
335 0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE,
338 dev_err(&port->dev, "Get MODEM STATus failed (error = %d)\n", rc);
343 dev_dbg(&port->dev, "get_modem_stat: 0x%x\n", *msr);
346 } /* mct_u232_get_modem_stat */
348 static void mct_u232_msr_to_icount(struct async_icount *icount,
351 /* Translate Control Line states */
352 if (msr & MCT_U232_MSR_DDSR)
354 if (msr & MCT_U232_MSR_DCTS)
356 if (msr & MCT_U232_MSR_DRI)
358 if (msr & MCT_U232_MSR_DCD)
360 } /* mct_u232_msr_to_icount */
362 static void mct_u232_msr_to_state(struct usb_serial_port *port,
363 unsigned int *control_state, unsigned char msr)
365 /* Translate Control Line states */
366 if (msr & MCT_U232_MSR_DSR)
367 *control_state |= TIOCM_DSR;
369 *control_state &= ~TIOCM_DSR;
370 if (msr & MCT_U232_MSR_CTS)
371 *control_state |= TIOCM_CTS;
373 *control_state &= ~TIOCM_CTS;
374 if (msr & MCT_U232_MSR_RI)
375 *control_state |= TIOCM_RI;
377 *control_state &= ~TIOCM_RI;
378 if (msr & MCT_U232_MSR_CD)
379 *control_state |= TIOCM_CD;
381 *control_state &= ~TIOCM_CD;
382 dev_dbg(&port->dev, "msr_to_state: msr=0x%x ==> state=0x%x\n", msr, *control_state);
383 } /* mct_u232_msr_to_state */
386 * Driver's tty interface functions
389 static int mct_u232_startup(struct usb_serial *serial)
391 struct mct_u232_private *priv;
392 struct usb_serial_port *port, *rport;
394 priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
397 spin_lock_init(&priv->lock);
398 init_waitqueue_head(&priv->msr_wait);
399 usb_set_serial_port_data(serial->port[0], priv);
401 init_waitqueue_head(&serial->port[0]->write_wait);
403 /* Puh, that's dirty */
404 port = serial->port[0];
405 rport = serial->port[1];
406 /* No unlinking, it wasn't submitted yet. */
407 usb_free_urb(port->read_urb);
408 port->read_urb = rport->interrupt_in_urb;
409 rport->interrupt_in_urb = NULL;
410 port->read_urb->context = port;
413 } /* mct_u232_startup */
416 static void mct_u232_release(struct usb_serial *serial)
418 struct mct_u232_private *priv;
421 for (i = 0; i < serial->num_ports; ++i) {
422 /* My special items, the standard routines free my urbs */
423 priv = usb_get_serial_port_data(serial->port[i]);
426 } /* mct_u232_release */
428 static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
430 struct usb_serial *serial = port->serial;
431 struct mct_u232_private *priv = usb_get_serial_port_data(port);
433 unsigned int control_state;
435 unsigned char last_lcr;
436 unsigned char last_msr;
438 /* Compensate for a hardware bug: although the Sitecom U232-P25
439 * device reports a maximum output packet size of 32 bytes,
440 * it seems to be able to accept only 16 bytes (and that's what
441 * SniffUSB says too...)
443 if (le16_to_cpu(serial->dev->descriptor.idProduct)
444 == MCT_U232_SITECOM_PID)
445 port->bulk_out_size = 16;
447 /* Do a defined restart: the normal serial device seems to
448 * always turn on DTR and RTS here, so do the same. I'm not
449 * sure if this is really necessary. But it should not harm
452 spin_lock_irqsave(&priv->lock, flags);
453 if (tty && (tty->termios.c_cflag & CBAUD))
454 priv->control_state = TIOCM_DTR | TIOCM_RTS;
456 priv->control_state = 0;
458 priv->last_lcr = (MCT_U232_DATA_BITS_8 |
459 MCT_U232_PARITY_NONE |
460 MCT_U232_STOP_BITS_1);
461 control_state = priv->control_state;
462 last_lcr = priv->last_lcr;
463 spin_unlock_irqrestore(&priv->lock, flags);
464 mct_u232_set_modem_ctrl(port, control_state);
465 mct_u232_set_line_ctrl(port, last_lcr);
467 /* Read modem status and update control state */
468 mct_u232_get_modem_stat(port, &last_msr);
469 spin_lock_irqsave(&priv->lock, flags);
470 priv->last_msr = last_msr;
471 mct_u232_msr_to_state(port, &priv->control_state, priv->last_msr);
472 spin_unlock_irqrestore(&priv->lock, flags);
474 retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
477 "usb_submit_urb(read bulk) failed pipe 0x%x err %d\n",
478 port->read_urb->pipe, retval);
482 retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
484 usb_kill_urb(port->read_urb);
486 "usb_submit_urb(read int) failed pipe 0x%x err %d",
487 port->interrupt_in_urb->pipe, retval);
494 } /* mct_u232_open */
496 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on)
498 unsigned int control_state;
499 struct mct_u232_private *priv = usb_get_serial_port_data(port);
501 mutex_lock(&port->serial->disc_mutex);
502 if (!port->serial->disconnected) {
503 /* drop DTR and RTS */
504 spin_lock_irq(&priv->lock);
506 priv->control_state |= TIOCM_DTR | TIOCM_RTS;
508 priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
509 control_state = priv->control_state;
510 spin_unlock_irq(&priv->lock);
511 mct_u232_set_modem_ctrl(port, control_state);
513 mutex_unlock(&port->serial->disc_mutex);
516 static void mct_u232_close(struct usb_serial_port *port)
518 if (port->serial->dev) {
519 /* shutdown our urbs */
520 usb_kill_urb(port->write_urb);
521 usb_kill_urb(port->read_urb);
522 usb_kill_urb(port->interrupt_in_urb);
524 } /* mct_u232_close */
527 static void mct_u232_read_int_callback(struct urb *urb)
529 struct usb_serial_port *port = urb->context;
530 struct mct_u232_private *priv = usb_get_serial_port_data(port);
531 struct tty_struct *tty;
532 unsigned char *data = urb->transfer_buffer;
534 int status = urb->status;
544 /* this urb is terminated, clean up */
545 dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
549 dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
554 usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
557 * Work-a-round: handle the 'usual' bulk-in pipe here
559 if (urb->transfer_buffer_length > 2) {
560 if (urb->actual_length) {
561 tty = tty_port_tty_get(&port->port);
563 tty_insert_flip_string(tty, data,
565 tty_flip_buffer_push(tty);
573 * The interrupt-in pipe signals exceptional conditions (modem line
574 * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
576 spin_lock_irqsave(&priv->lock, flags);
577 priv->last_msr = data[MCT_U232_MSR_INDEX];
579 /* Record Control Line states */
580 mct_u232_msr_to_state(port, &priv->control_state, priv->last_msr);
582 mct_u232_msr_to_icount(&priv->icount, priv->last_msr);
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];
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.
593 if (priv->last_lsr & MCT_U232_LSR_ERR) {
594 tty = tty_port_tty_get(&port->port);
596 if (priv->last_lsr & MCT_U232_LSR_OE) {
599 if (priv->last_lsr & MCT_U232_LSR_PE) {
602 if (priv->last_lsr & MCT_U232_LSR_FE) {
604 /* Break Indicator */
605 if (priv->last_lsr & MCT_U232_LSR_BI) {
610 wake_up_interruptible(&priv->msr_wait);
611 spin_unlock_irqrestore(&priv->lock, flags);
613 retval = usb_submit_urb(urb, GFP_ATOMIC);
616 "%s - usb_submit_urb failed with result %d\n",
618 } /* mct_u232_read_int_callback */
620 static void mct_u232_set_termios(struct tty_struct *tty,
621 struct usb_serial_port *port,
622 struct ktermios *old_termios)
624 struct usb_serial *serial = port->serial;
625 struct mct_u232_private *priv = usb_get_serial_port_data(port);
626 struct ktermios *termios = &tty->termios;
627 unsigned int cflag = termios->c_cflag;
628 unsigned int old_cflag = old_termios->c_cflag;
630 unsigned int control_state;
631 unsigned char last_lcr;
633 /* get a local copy of the current port settings */
634 spin_lock_irqsave(&priv->lock, flags);
635 control_state = priv->control_state;
636 spin_unlock_irqrestore(&priv->lock, flags);
641 * Do not attempt to cache old rates and skip settings,
642 * disconnects screw such tricks up completely.
643 * Premature optimization is the root of all evil.
646 /* reassert DTR and RTS on transition from B0 */
647 if ((old_cflag & CBAUD) == B0) {
648 dev_dbg(&port->dev, "%s: baud was B0\n", __func__);
649 control_state |= TIOCM_DTR | TIOCM_RTS;
650 mct_u232_set_modem_ctrl(port, control_state);
653 mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty));
655 if ((cflag & CBAUD) == B0) {
656 dev_dbg(&port->dev, "%s: baud is B0\n", __func__);
657 /* Drop RTS and DTR */
658 control_state &= ~(TIOCM_DTR | TIOCM_RTS);
659 mct_u232_set_modem_ctrl(port, control_state);
663 * Update line control register (LCR)
668 last_lcr |= (cflag & PARODD) ?
669 MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
671 last_lcr |= MCT_U232_PARITY_NONE;
673 /* set the number of data bits */
674 switch (cflag & CSIZE) {
676 last_lcr |= MCT_U232_DATA_BITS_5; break;
678 last_lcr |= MCT_U232_DATA_BITS_6; break;
680 last_lcr |= MCT_U232_DATA_BITS_7; break;
682 last_lcr |= MCT_U232_DATA_BITS_8; break;
685 "CSIZE was not CS5-CS8, using default of 8\n");
686 last_lcr |= MCT_U232_DATA_BITS_8;
690 termios->c_cflag &= ~CMSPAR;
692 /* set the number of stop bits */
693 last_lcr |= (cflag & CSTOPB) ?
694 MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
696 mct_u232_set_line_ctrl(port, last_lcr);
698 /* save off the modified port settings */
699 spin_lock_irqsave(&priv->lock, flags);
700 priv->control_state = control_state;
701 priv->last_lcr = last_lcr;
702 spin_unlock_irqrestore(&priv->lock, flags);
703 } /* mct_u232_set_termios */
705 static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
707 struct usb_serial_port *port = tty->driver_data;
708 struct mct_u232_private *priv = usb_get_serial_port_data(port);
712 spin_lock_irqsave(&priv->lock, flags);
713 lcr = priv->last_lcr;
716 lcr |= MCT_U232_SET_BREAK;
717 spin_unlock_irqrestore(&priv->lock, flags);
719 mct_u232_set_line_ctrl(port, lcr);
720 } /* mct_u232_break_ctl */
723 static int mct_u232_tiocmget(struct tty_struct *tty)
725 struct usb_serial_port *port = tty->driver_data;
726 struct mct_u232_private *priv = usb_get_serial_port_data(port);
727 unsigned int control_state;
730 spin_lock_irqsave(&priv->lock, flags);
731 control_state = priv->control_state;
732 spin_unlock_irqrestore(&priv->lock, flags);
734 return control_state;
737 static int mct_u232_tiocmset(struct tty_struct *tty,
738 unsigned int set, unsigned int clear)
740 struct usb_serial_port *port = tty->driver_data;
741 struct mct_u232_private *priv = usb_get_serial_port_data(port);
742 unsigned int control_state;
745 spin_lock_irqsave(&priv->lock, flags);
746 control_state = priv->control_state;
749 control_state |= TIOCM_RTS;
751 control_state |= TIOCM_DTR;
752 if (clear & TIOCM_RTS)
753 control_state &= ~TIOCM_RTS;
754 if (clear & TIOCM_DTR)
755 control_state &= ~TIOCM_DTR;
757 priv->control_state = control_state;
758 spin_unlock_irqrestore(&priv->lock, flags);
759 return mct_u232_set_modem_ctrl(port, control_state);
762 static void mct_u232_throttle(struct tty_struct *tty)
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;
768 spin_lock_irq(&priv->lock);
769 priv->rx_flags |= THROTTLED;
770 if (C_CRTSCTS(tty)) {
771 priv->control_state &= ~TIOCM_RTS;
772 control_state = priv->control_state;
773 spin_unlock_irq(&priv->lock);
774 mct_u232_set_modem_ctrl(port, control_state);
776 spin_unlock_irq(&priv->lock);
780 static void mct_u232_unthrottle(struct tty_struct *tty)
782 struct usb_serial_port *port = tty->driver_data;
783 struct mct_u232_private *priv = usb_get_serial_port_data(port);
784 unsigned int control_state;
786 spin_lock_irq(&priv->lock);
787 if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
788 priv->rx_flags &= ~THROTTLED;
789 priv->control_state |= TIOCM_RTS;
790 control_state = priv->control_state;
791 spin_unlock_irq(&priv->lock);
792 mct_u232_set_modem_ctrl(port, control_state);
794 spin_unlock_irq(&priv->lock);
798 static int mct_u232_ioctl(struct tty_struct *tty,
799 unsigned int cmd, unsigned long arg)
802 struct usb_serial_port *port = tty->driver_data;
803 struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port);
804 struct async_icount cnow, cprev;
807 dev_dbg(&port->dev, "%s - cmd = 0x%x\n", __func__, cmd);
813 dev_dbg(&port->dev, "%s TIOCMIWAIT", __func__);
815 spin_lock_irqsave(&mct_u232_port->lock, flags);
816 cprev = mct_u232_port->icount;
817 spin_unlock_irqrestore(&mct_u232_port->lock, flags);
819 prepare_to_wait(&mct_u232_port->msr_wait,
820 &wait, TASK_INTERRUPTIBLE);
822 finish_wait(&mct_u232_port->msr_wait, &wait);
823 /* see if a signal did it */
824 if (signal_pending(current))
826 spin_lock_irqsave(&mct_u232_port->lock, flags);
827 cnow = mct_u232_port->icount;
828 spin_unlock_irqrestore(&mct_u232_port->lock, flags);
829 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
830 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
831 return -EIO; /* no change => error */
832 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
833 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
834 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
835 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
845 static int mct_u232_get_icount(struct tty_struct *tty,
846 struct serial_icounter_struct *icount)
848 struct usb_serial_port *port = tty->driver_data;
849 struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port);
850 struct async_icount *ic = &mct_u232_port->icount;
853 spin_lock_irqsave(&mct_u232_port->lock, flags);
855 icount->cts = ic->cts;
856 icount->dsr = ic->dsr;
857 icount->rng = ic->rng;
858 icount->dcd = ic->dcd;
861 icount->frame = ic->frame;
862 icount->overrun = ic->overrun;
863 icount->parity = ic->parity;
864 icount->brk = ic->brk;
865 icount->buf_overrun = ic->buf_overrun;
867 spin_unlock_irqrestore(&mct_u232_port->lock, flags);
869 dev_dbg(&port->dev, "%s TIOCGICOUNT RX=%d, TX=%d\n",
870 __func__, icount->rx, icount->tx);
874 module_usb_serial_driver(serial_drivers, id_table);
876 MODULE_AUTHOR(DRIVER_AUTHOR);
877 MODULE_DESCRIPTION(DRIVER_DESC);
878 MODULE_LICENSE("GPL");