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>
41 #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
42 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
47 static int mct_u232_startup(struct usb_serial *serial);
48 static int mct_u232_port_probe(struct usb_serial_port *port);
49 static int mct_u232_port_remove(struct usb_serial_port *remove);
50 static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);
51 static void mct_u232_close(struct usb_serial_port *port);
52 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on);
53 static void mct_u232_read_int_callback(struct urb *urb);
54 static void mct_u232_set_termios(struct tty_struct *tty,
55 struct usb_serial_port *port, struct ktermios *old);
56 static void mct_u232_break_ctl(struct tty_struct *tty, int break_state);
57 static int mct_u232_tiocmget(struct tty_struct *tty);
58 static int mct_u232_tiocmset(struct tty_struct *tty,
59 unsigned int set, unsigned int clear);
60 static int mct_u232_ioctl(struct tty_struct *tty,
61 unsigned int cmd, unsigned long arg);
62 static void mct_u232_throttle(struct tty_struct *tty);
63 static void mct_u232_unthrottle(struct tty_struct *tty);
67 * All of the device info needed for the MCT USB-RS232 converter.
69 static const struct usb_device_id id_table[] = {
70 { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
71 { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
72 { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
73 { USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },
74 { } /* Terminating entry */
76 MODULE_DEVICE_TABLE(usb, id_table);
78 static struct usb_serial_driver mct_u232_device = {
83 .description = "MCT U232",
86 .open = mct_u232_open,
87 .close = mct_u232_close,
88 .dtr_rts = mct_u232_dtr_rts,
89 .throttle = mct_u232_throttle,
90 .unthrottle = mct_u232_unthrottle,
91 .read_int_callback = mct_u232_read_int_callback,
92 .set_termios = mct_u232_set_termios,
93 .break_ctl = mct_u232_break_ctl,
94 .tiocmget = mct_u232_tiocmget,
95 .tiocmset = mct_u232_tiocmset,
96 .attach = mct_u232_startup,
97 .port_probe = mct_u232_port_probe,
98 .port_remove = mct_u232_port_remove,
99 .ioctl = mct_u232_ioctl,
100 .get_icount = usb_serial_generic_get_icount,
103 static struct usb_serial_driver * const serial_drivers[] = {
104 &mct_u232_device, NULL
107 struct mct_u232_private {
109 unsigned int control_state; /* Modem Line Setting (TIOCM) */
110 unsigned char last_lcr; /* Line Control Register */
111 unsigned char last_lsr; /* Line Status Register */
112 unsigned char last_msr; /* Modem Status Register */
113 unsigned int rx_flags; /* Throttling flags */
116 #define THROTTLED 0x01
119 * Handle vendor specific USB requests
122 #define WDR_TIMEOUT 5000 /* default urb timeout */
125 * Later day 2.6.0-test kernels have new baud rates like B230400 which
126 * we do not know how to support. We ignore them for the moment.
128 static int mct_u232_calculate_baud_rate(struct usb_serial *serial,
129 speed_t value, speed_t *result)
133 if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
134 || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
139 return 0x02; /* this one not tested */
161 /* FIXME: Can we use any divider - should we do
162 divider = 115200/value;
163 real baud = 115200/divider */
183 static int mct_u232_set_baud_rate(struct tty_struct *tty,
184 struct usb_serial *serial, struct usb_serial_port *port, speed_t value)
186 unsigned int divisor;
189 unsigned char cts_enable_byte = 0;
192 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
196 divisor = mct_u232_calculate_baud_rate(serial, value, &speed);
197 put_unaligned_le32(cpu_to_le32(divisor), buf);
198 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
199 MCT_U232_SET_BAUD_RATE_REQUEST,
200 MCT_U232_SET_REQUEST_TYPE,
201 0, 0, buf, MCT_U232_SET_BAUD_RATE_SIZE,
203 if (rc < 0) /*FIXME: What value speed results */
204 dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n",
207 tty_encode_baud_rate(tty, speed, speed);
208 dev_dbg(&port->dev, "set_baud_rate: value: 0x%x, divisor: 0x%x\n", value, divisor);
210 /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
211 always sends two extra USB 'device request' messages after the
212 'baud rate change' message. The actual functionality of the
213 request codes in these messages is not fully understood but these
214 particular codes are never seen in any operation besides a baud
215 rate change. Both of these messages send a single byte of data.
216 In the first message, the value of this byte is always zero.
218 The second message has been determined experimentally to control
219 whether data will be transmitted to a device which is not asserting
220 the 'CTS' signal. If the second message's data byte is zero, data
221 will be transmitted even if 'CTS' is not asserted (i.e. no hardware
222 flow control). if the second message's data byte is nonzero (a
223 value of 1 is used by this driver), data will not be transmitted to
224 a device which is not asserting 'CTS'.
228 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
229 MCT_U232_SET_UNKNOWN1_REQUEST,
230 MCT_U232_SET_REQUEST_TYPE,
231 0, 0, buf, MCT_U232_SET_UNKNOWN1_SIZE,
234 dev_err(&port->dev, "Sending USB device request code %d "
235 "failed (error = %d)\n", MCT_U232_SET_UNKNOWN1_REQUEST,
238 if (port && C_CRTSCTS(tty))
241 dev_dbg(&port->dev, "set_baud_rate: send second control message, data = %02X\n",
243 buf[0] = cts_enable_byte;
244 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
245 MCT_U232_SET_CTS_REQUEST,
246 MCT_U232_SET_REQUEST_TYPE,
247 0, 0, buf, MCT_U232_SET_CTS_SIZE,
250 dev_err(&port->dev, "Sending USB device request code %d "
251 "failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc);
255 } /* mct_u232_set_baud_rate */
257 static int mct_u232_set_line_ctrl(struct usb_serial_port *port,
263 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
268 rc = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
269 MCT_U232_SET_LINE_CTRL_REQUEST,
270 MCT_U232_SET_REQUEST_TYPE,
271 0, 0, buf, MCT_U232_SET_LINE_CTRL_SIZE,
274 dev_err(&port->dev, "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc);
275 dev_dbg(&port->dev, "set_line_ctrl: 0x%x\n", lcr);
278 } /* mct_u232_set_line_ctrl */
280 static int mct_u232_set_modem_ctrl(struct usb_serial_port *port,
281 unsigned int control_state)
287 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
291 mcr = MCT_U232_MCR_NONE;
292 if (control_state & TIOCM_DTR)
293 mcr |= MCT_U232_MCR_DTR;
294 if (control_state & TIOCM_RTS)
295 mcr |= MCT_U232_MCR_RTS;
298 rc = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
299 MCT_U232_SET_MODEM_CTRL_REQUEST,
300 MCT_U232_SET_REQUEST_TYPE,
301 0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE,
305 dev_dbg(&port->dev, "set_modem_ctrl: state=0x%x ==> mcr=0x%x\n", control_state, mcr);
308 dev_err(&port->dev, "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc);
312 } /* mct_u232_set_modem_ctrl */
314 static int mct_u232_get_modem_stat(struct usb_serial_port *port,
320 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
325 rc = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0),
326 MCT_U232_GET_MODEM_STAT_REQUEST,
327 MCT_U232_GET_REQUEST_TYPE,
328 0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE,
331 dev_err(&port->dev, "Get MODEM STATus failed (error = %d)\n", rc);
336 dev_dbg(&port->dev, "get_modem_stat: 0x%x\n", *msr);
339 } /* mct_u232_get_modem_stat */
341 static void mct_u232_msr_to_icount(struct async_icount *icount,
344 /* Translate Control Line states */
345 if (msr & MCT_U232_MSR_DDSR)
347 if (msr & MCT_U232_MSR_DCTS)
349 if (msr & MCT_U232_MSR_DRI)
351 if (msr & MCT_U232_MSR_DCD)
353 } /* mct_u232_msr_to_icount */
355 static void mct_u232_msr_to_state(struct usb_serial_port *port,
356 unsigned int *control_state, unsigned char msr)
358 /* Translate Control Line states */
359 if (msr & MCT_U232_MSR_DSR)
360 *control_state |= TIOCM_DSR;
362 *control_state &= ~TIOCM_DSR;
363 if (msr & MCT_U232_MSR_CTS)
364 *control_state |= TIOCM_CTS;
366 *control_state &= ~TIOCM_CTS;
367 if (msr & MCT_U232_MSR_RI)
368 *control_state |= TIOCM_RI;
370 *control_state &= ~TIOCM_RI;
371 if (msr & MCT_U232_MSR_CD)
372 *control_state |= TIOCM_CD;
374 *control_state &= ~TIOCM_CD;
375 dev_dbg(&port->dev, "msr_to_state: msr=0x%x ==> state=0x%x\n", msr, *control_state);
376 } /* mct_u232_msr_to_state */
379 * Driver's tty interface functions
382 static int mct_u232_startup(struct usb_serial *serial)
384 struct usb_serial_port *port, *rport;
386 /* Puh, that's dirty */
387 port = serial->port[0];
388 rport = serial->port[1];
389 /* No unlinking, it wasn't submitted yet. */
390 usb_free_urb(port->read_urb);
391 port->read_urb = rport->interrupt_in_urb;
392 rport->interrupt_in_urb = NULL;
393 port->read_urb->context = port;
396 } /* mct_u232_startup */
398 static int mct_u232_port_probe(struct usb_serial_port *port)
400 struct mct_u232_private *priv;
402 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
406 spin_lock_init(&priv->lock);
408 usb_set_serial_port_data(port, priv);
413 static int mct_u232_port_remove(struct usb_serial_port *port)
415 struct mct_u232_private *priv;
417 priv = usb_get_serial_port_data(port);
423 static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
425 struct usb_serial *serial = port->serial;
426 struct mct_u232_private *priv = usb_get_serial_port_data(port);
428 unsigned int control_state;
430 unsigned char last_lcr;
431 unsigned char last_msr;
433 /* Compensate for a hardware bug: although the Sitecom U232-P25
434 * device reports a maximum output packet size of 32 bytes,
435 * it seems to be able to accept only 16 bytes (and that's what
436 * SniffUSB says too...)
438 if (le16_to_cpu(serial->dev->descriptor.idProduct)
439 == MCT_U232_SITECOM_PID)
440 port->bulk_out_size = 16;
442 /* Do a defined restart: the normal serial device seems to
443 * always turn on DTR and RTS here, so do the same. I'm not
444 * sure if this is really necessary. But it should not harm
447 spin_lock_irqsave(&priv->lock, flags);
448 if (tty && (tty->termios.c_cflag & CBAUD))
449 priv->control_state = TIOCM_DTR | TIOCM_RTS;
451 priv->control_state = 0;
453 priv->last_lcr = (MCT_U232_DATA_BITS_8 |
454 MCT_U232_PARITY_NONE |
455 MCT_U232_STOP_BITS_1);
456 control_state = priv->control_state;
457 last_lcr = priv->last_lcr;
458 spin_unlock_irqrestore(&priv->lock, flags);
459 mct_u232_set_modem_ctrl(port, control_state);
460 mct_u232_set_line_ctrl(port, last_lcr);
462 /* Read modem status and update control state */
463 mct_u232_get_modem_stat(port, &last_msr);
464 spin_lock_irqsave(&priv->lock, flags);
465 priv->last_msr = last_msr;
466 mct_u232_msr_to_state(port, &priv->control_state, priv->last_msr);
467 spin_unlock_irqrestore(&priv->lock, flags);
469 retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
472 "usb_submit_urb(read bulk) failed pipe 0x%x err %d\n",
473 port->read_urb->pipe, retval);
477 retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
479 usb_kill_urb(port->read_urb);
481 "usb_submit_urb(read int) failed pipe 0x%x err %d",
482 port->interrupt_in_urb->pipe, retval);
489 } /* mct_u232_open */
491 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on)
493 unsigned int control_state;
494 struct mct_u232_private *priv = usb_get_serial_port_data(port);
496 spin_lock_irq(&priv->lock);
498 priv->control_state |= TIOCM_DTR | TIOCM_RTS;
500 priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
501 control_state = priv->control_state;
502 spin_unlock_irq(&priv->lock);
504 mct_u232_set_modem_ctrl(port, control_state);
507 static void mct_u232_close(struct usb_serial_port *port)
510 * Must kill the read urb as it is actually an interrupt urb, which
511 * generic close thus fails to kill.
513 usb_kill_urb(port->read_urb);
514 usb_kill_urb(port->interrupt_in_urb);
516 usb_serial_generic_close(port);
517 } /* mct_u232_close */
520 static void mct_u232_read_int_callback(struct urb *urb)
522 struct usb_serial_port *port = urb->context;
523 struct mct_u232_private *priv = usb_get_serial_port_data(port);
524 unsigned char *data = urb->transfer_buffer;
526 int status = urb->status;
536 /* this urb is terminated, clean up */
537 dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
541 dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
546 usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
549 * Work-a-round: handle the 'usual' bulk-in pipe here
551 if (urb->transfer_buffer_length > 2) {
552 if (urb->actual_length) {
553 tty_insert_flip_string(&port->port, data,
555 tty_flip_buffer_push(&port->port);
561 * The interrupt-in pipe signals exceptional conditions (modem line
562 * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
564 spin_lock_irqsave(&priv->lock, flags);
565 priv->last_msr = data[MCT_U232_MSR_INDEX];
567 /* Record Control Line states */
568 mct_u232_msr_to_state(port, &priv->control_state, priv->last_msr);
570 mct_u232_msr_to_icount(&port->icount, priv->last_msr);
573 /* Not yet handled. See belkin_sa.c for further information */
574 /* Now to report any errors */
575 priv->last_lsr = data[MCT_U232_LSR_INDEX];
577 * fill in the flip buffer here, but I do not know the relation
578 * to the current/next receive buffer or characters. I need
579 * to look in to this before committing any code.
581 if (priv->last_lsr & MCT_U232_LSR_ERR) {
582 tty = tty_port_tty_get(&port->port);
584 if (priv->last_lsr & MCT_U232_LSR_OE) {
587 if (priv->last_lsr & MCT_U232_LSR_PE) {
590 if (priv->last_lsr & MCT_U232_LSR_FE) {
592 /* Break Indicator */
593 if (priv->last_lsr & MCT_U232_LSR_BI) {
598 wake_up_interruptible(&port->delta_msr_wait);
599 spin_unlock_irqrestore(&priv->lock, flags);
601 retval = usb_submit_urb(urb, GFP_ATOMIC);
604 "%s - usb_submit_urb failed with result %d\n",
606 } /* mct_u232_read_int_callback */
608 static void mct_u232_set_termios(struct tty_struct *tty,
609 struct usb_serial_port *port,
610 struct ktermios *old_termios)
612 struct usb_serial *serial = port->serial;
613 struct mct_u232_private *priv = usb_get_serial_port_data(port);
614 struct ktermios *termios = &tty->termios;
615 unsigned int cflag = termios->c_cflag;
616 unsigned int old_cflag = old_termios->c_cflag;
618 unsigned int control_state;
619 unsigned char last_lcr;
621 /* get a local copy of the current port settings */
622 spin_lock_irqsave(&priv->lock, flags);
623 control_state = priv->control_state;
624 spin_unlock_irqrestore(&priv->lock, flags);
629 * Do not attempt to cache old rates and skip settings,
630 * disconnects screw such tricks up completely.
631 * Premature optimization is the root of all evil.
634 /* reassert DTR and RTS on transition from B0 */
635 if ((old_cflag & CBAUD) == B0) {
636 dev_dbg(&port->dev, "%s: baud was B0\n", __func__);
637 control_state |= TIOCM_DTR | TIOCM_RTS;
638 mct_u232_set_modem_ctrl(port, control_state);
641 mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty));
643 if ((cflag & CBAUD) == B0) {
644 dev_dbg(&port->dev, "%s: baud is B0\n", __func__);
645 /* Drop RTS and DTR */
646 control_state &= ~(TIOCM_DTR | TIOCM_RTS);
647 mct_u232_set_modem_ctrl(port, control_state);
651 * Update line control register (LCR)
656 last_lcr |= (cflag & PARODD) ?
657 MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
659 last_lcr |= MCT_U232_PARITY_NONE;
661 /* set the number of data bits */
662 switch (cflag & CSIZE) {
664 last_lcr |= MCT_U232_DATA_BITS_5; break;
666 last_lcr |= MCT_U232_DATA_BITS_6; break;
668 last_lcr |= MCT_U232_DATA_BITS_7; break;
670 last_lcr |= MCT_U232_DATA_BITS_8; break;
673 "CSIZE was not CS5-CS8, using default of 8\n");
674 last_lcr |= MCT_U232_DATA_BITS_8;
678 termios->c_cflag &= ~CMSPAR;
680 /* set the number of stop bits */
681 last_lcr |= (cflag & CSTOPB) ?
682 MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
684 mct_u232_set_line_ctrl(port, last_lcr);
686 /* save off the modified port settings */
687 spin_lock_irqsave(&priv->lock, flags);
688 priv->control_state = control_state;
689 priv->last_lcr = last_lcr;
690 spin_unlock_irqrestore(&priv->lock, flags);
691 } /* mct_u232_set_termios */
693 static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
695 struct usb_serial_port *port = tty->driver_data;
696 struct mct_u232_private *priv = usb_get_serial_port_data(port);
700 spin_lock_irqsave(&priv->lock, flags);
701 lcr = priv->last_lcr;
704 lcr |= MCT_U232_SET_BREAK;
705 spin_unlock_irqrestore(&priv->lock, flags);
707 mct_u232_set_line_ctrl(port, lcr);
708 } /* mct_u232_break_ctl */
711 static int mct_u232_tiocmget(struct tty_struct *tty)
713 struct usb_serial_port *port = tty->driver_data;
714 struct mct_u232_private *priv = usb_get_serial_port_data(port);
715 unsigned int control_state;
718 spin_lock_irqsave(&priv->lock, flags);
719 control_state = priv->control_state;
720 spin_unlock_irqrestore(&priv->lock, flags);
722 return control_state;
725 static int mct_u232_tiocmset(struct tty_struct *tty,
726 unsigned int set, unsigned int clear)
728 struct usb_serial_port *port = tty->driver_data;
729 struct mct_u232_private *priv = usb_get_serial_port_data(port);
730 unsigned int control_state;
733 spin_lock_irqsave(&priv->lock, flags);
734 control_state = priv->control_state;
737 control_state |= TIOCM_RTS;
739 control_state |= TIOCM_DTR;
740 if (clear & TIOCM_RTS)
741 control_state &= ~TIOCM_RTS;
742 if (clear & TIOCM_DTR)
743 control_state &= ~TIOCM_DTR;
745 priv->control_state = control_state;
746 spin_unlock_irqrestore(&priv->lock, flags);
747 return mct_u232_set_modem_ctrl(port, control_state);
750 static void mct_u232_throttle(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 priv->rx_flags |= THROTTLED;
758 if (C_CRTSCTS(tty)) {
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 static void mct_u232_unthrottle(struct tty_struct *tty)
770 struct usb_serial_port *port = tty->driver_data;
771 struct mct_u232_private *priv = usb_get_serial_port_data(port);
772 unsigned int control_state;
774 spin_lock_irq(&priv->lock);
775 if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
776 priv->rx_flags &= ~THROTTLED;
777 priv->control_state |= TIOCM_RTS;
778 control_state = priv->control_state;
779 spin_unlock_irq(&priv->lock);
780 mct_u232_set_modem_ctrl(port, control_state);
782 spin_unlock_irq(&priv->lock);
786 static int mct_u232_ioctl(struct tty_struct *tty,
787 unsigned int cmd, unsigned long arg)
790 struct usb_serial_port *port = tty->driver_data;
791 struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port);
792 struct async_icount cnow, cprev;
795 dev_dbg(&port->dev, "%s - cmd = 0x%x\n", __func__, cmd);
801 dev_dbg(&port->dev, "%s TIOCMIWAIT", __func__);
803 spin_lock_irqsave(&mct_u232_port->lock, flags);
804 cprev = port->icount;
805 spin_unlock_irqrestore(&mct_u232_port->lock, flags);
807 prepare_to_wait(&port->delta_msr_wait,
808 &wait, TASK_INTERRUPTIBLE);
810 finish_wait(&port->delta_msr_wait, &wait);
811 /* see if a signal did it */
812 if (signal_pending(current))
815 if (port->serial->disconnected)
818 spin_lock_irqsave(&mct_u232_port->lock, flags);
820 spin_unlock_irqrestore(&mct_u232_port->lock, flags);
821 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
822 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
823 return -EIO; /* no change => error */
824 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
825 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
826 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
827 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
837 module_usb_serial_driver(serial_drivers, id_table);
839 MODULE_AUTHOR(DRIVER_AUTHOR);
840 MODULE_DESCRIPTION(DRIVER_DESC);
841 MODULE_LICENSE("GPL");