1 // SPDX-License-Identifier: GPL-2.0+
3 * MCT (Magic Control Technology Corp.) USB RS232 Converter Driver
7 * This program is largely derived from the Belkin USB Serial Adapter Driver
8 * (see belkin_sa.[ch]). All of the information about the device was acquired
9 * by using SniffUSB on Windows98. For technical details see mct_u232.h.
11 * William G. Greathouse and Greg Kroah-Hartman provided great help on how to
12 * do the reverse engineering and how to write a USB serial device driver.
14 * TO BE DONE, TO BE CHECKED:
15 * DTR/RTS signal handling may be incomplete or incorrect. I have mainly
16 * implemented what I have seen with SniffUSB or found in belkin_sa.c.
17 * For further TODOs check also belkin_sa.c.
20 #include <linux/kernel.h>
21 #include <linux/errno.h>
22 #include <linux/slab.h>
23 #include <linux/tty.h>
24 #include <linux/tty_driver.h>
25 #include <linux/tty_flip.h>
26 #include <linux/module.h>
27 #include <linux/spinlock.h>
28 #include <linux/uaccess.h>
29 #include <asm/unaligned.h>
30 #include <linux/usb.h>
31 #include <linux/usb/serial.h>
32 #include <linux/serial.h>
36 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
41 static int mct_u232_port_probe(struct usb_serial_port *port);
42 static void mct_u232_port_remove(struct usb_serial_port *remove);
43 static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);
44 static void mct_u232_close(struct usb_serial_port *port);
45 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on);
46 static void mct_u232_read_int_callback(struct urb *urb);
47 static void mct_u232_set_termios(struct tty_struct *tty,
48 struct usb_serial_port *port,
49 const struct ktermios *old_termios);
50 static void mct_u232_break_ctl(struct tty_struct *tty, int break_state);
51 static int mct_u232_tiocmget(struct tty_struct *tty);
52 static int mct_u232_tiocmset(struct tty_struct *tty,
53 unsigned int set, unsigned int clear);
54 static void mct_u232_throttle(struct tty_struct *tty);
55 static void mct_u232_unthrottle(struct tty_struct *tty);
59 * All of the device info needed for the MCT USB-RS232 converter.
61 static const struct usb_device_id id_table[] = {
62 { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
63 { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
64 { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
65 { USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },
66 { } /* Terminating entry */
68 MODULE_DEVICE_TABLE(usb, id_table);
70 static struct usb_serial_driver mct_u232_device = {
75 .description = "MCT U232",
78 .open = mct_u232_open,
79 .close = mct_u232_close,
80 .dtr_rts = mct_u232_dtr_rts,
81 .throttle = mct_u232_throttle,
82 .unthrottle = mct_u232_unthrottle,
83 .read_int_callback = mct_u232_read_int_callback,
84 .set_termios = mct_u232_set_termios,
85 .break_ctl = mct_u232_break_ctl,
86 .tiocmget = mct_u232_tiocmget,
87 .tiocmset = mct_u232_tiocmset,
88 .tiocmiwait = usb_serial_generic_tiocmiwait,
89 .port_probe = mct_u232_port_probe,
90 .port_remove = mct_u232_port_remove,
91 .get_icount = usb_serial_generic_get_icount,
94 static struct usb_serial_driver * const serial_drivers[] = {
95 &mct_u232_device, NULL
98 struct mct_u232_private {
101 unsigned int control_state; /* Modem Line Setting (TIOCM) */
102 unsigned char last_lcr; /* Line Control Register */
103 unsigned char last_lsr; /* Line Status Register */
104 unsigned char last_msr; /* Modem Status Register */
105 unsigned int rx_flags; /* Throttling flags */
108 #define THROTTLED 0x01
111 * Handle vendor specific USB requests
114 #define WDR_TIMEOUT 5000 /* default urb timeout */
117 * Later day 2.6.0-test kernels have new baud rates like B230400 which
118 * we do not know how to support. We ignore them for the moment.
120 static int mct_u232_calculate_baud_rate(struct usb_serial *serial,
121 speed_t value, speed_t *result)
125 if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
126 || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
131 return 0x02; /* this one not tested */
153 /* FIXME: Can we use any divider - should we do
154 divider = 115200/value;
155 real baud = 115200/divider */
175 static int mct_u232_set_baud_rate(struct tty_struct *tty,
176 struct usb_serial *serial, struct usb_serial_port *port, speed_t value)
178 unsigned int divisor;
181 unsigned char cts_enable_byte = 0;
184 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
188 divisor = mct_u232_calculate_baud_rate(serial, value, &speed);
189 put_unaligned_le32(divisor, buf);
190 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
191 MCT_U232_SET_BAUD_RATE_REQUEST,
192 MCT_U232_SET_REQUEST_TYPE,
193 0, 0, buf, MCT_U232_SET_BAUD_RATE_SIZE,
195 if (rc < 0) /*FIXME: What value speed results */
196 dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n",
199 tty_encode_baud_rate(tty, speed, speed);
200 dev_dbg(&port->dev, "set_baud_rate: value: 0x%x, divisor: 0x%x\n", value, divisor);
202 /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
203 always sends two extra USB 'device request' messages after the
204 'baud rate change' message. The actual functionality of the
205 request codes in these messages is not fully understood but these
206 particular codes are never seen in any operation besides a baud
207 rate change. Both of these messages send a single byte of data.
208 In the first message, the value of this byte is always zero.
210 The second message has been determined experimentally to control
211 whether data will be transmitted to a device which is not asserting
212 the 'CTS' signal. If the second message's data byte is zero, data
213 will be transmitted even if 'CTS' is not asserted (i.e. no hardware
214 flow control). if the second message's data byte is nonzero (a
215 value of 1 is used by this driver), data will not be transmitted to
216 a device which is not asserting 'CTS'.
220 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
221 MCT_U232_SET_UNKNOWN1_REQUEST,
222 MCT_U232_SET_REQUEST_TYPE,
223 0, 0, buf, MCT_U232_SET_UNKNOWN1_SIZE,
226 dev_err(&port->dev, "Sending USB device request code %d "
227 "failed (error = %d)\n", MCT_U232_SET_UNKNOWN1_REQUEST,
230 if (port && C_CRTSCTS(tty))
233 dev_dbg(&port->dev, "set_baud_rate: send second control message, data = %02X\n",
235 buf[0] = cts_enable_byte;
236 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
237 MCT_U232_SET_CTS_REQUEST,
238 MCT_U232_SET_REQUEST_TYPE,
239 0, 0, buf, MCT_U232_SET_CTS_SIZE,
242 dev_err(&port->dev, "Sending USB device request code %d "
243 "failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc);
247 } /* mct_u232_set_baud_rate */
249 static int mct_u232_set_line_ctrl(struct usb_serial_port *port,
255 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
260 rc = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
261 MCT_U232_SET_LINE_CTRL_REQUEST,
262 MCT_U232_SET_REQUEST_TYPE,
263 0, 0, buf, MCT_U232_SET_LINE_CTRL_SIZE,
266 dev_err(&port->dev, "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc);
267 dev_dbg(&port->dev, "set_line_ctrl: 0x%x\n", lcr);
270 } /* mct_u232_set_line_ctrl */
272 static int mct_u232_set_modem_ctrl(struct usb_serial_port *port,
273 unsigned int control_state)
279 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
283 mcr = MCT_U232_MCR_NONE;
284 if (control_state & TIOCM_DTR)
285 mcr |= MCT_U232_MCR_DTR;
286 if (control_state & TIOCM_RTS)
287 mcr |= MCT_U232_MCR_RTS;
290 rc = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
291 MCT_U232_SET_MODEM_CTRL_REQUEST,
292 MCT_U232_SET_REQUEST_TYPE,
293 0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE,
297 dev_dbg(&port->dev, "set_modem_ctrl: state=0x%x ==> mcr=0x%x\n", control_state, mcr);
300 dev_err(&port->dev, "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc);
304 } /* mct_u232_set_modem_ctrl */
306 static int mct_u232_get_modem_stat(struct usb_serial_port *port,
312 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
317 rc = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0),
318 MCT_U232_GET_MODEM_STAT_REQUEST,
319 MCT_U232_GET_REQUEST_TYPE,
320 0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE,
322 if (rc < MCT_U232_GET_MODEM_STAT_SIZE) {
323 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 usb_serial *serial = port->serial;
381 struct mct_u232_private *priv;
383 /* check first to simplify error handling */
384 if (!serial->port[1] || !serial->port[1]->interrupt_in_urb) {
385 dev_err(&port->dev, "expected endpoint missing\n");
389 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
393 /* Use second interrupt-in endpoint for reading. */
394 priv->read_urb = serial->port[1]->interrupt_in_urb;
395 priv->read_urb->context = port;
397 spin_lock_init(&priv->lock);
399 usb_set_serial_port_data(port, priv);
404 static void mct_u232_port_remove(struct usb_serial_port *port)
406 struct mct_u232_private *priv;
408 priv = usb_get_serial_port_data(port);
412 static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
414 struct usb_serial *serial = port->serial;
415 struct mct_u232_private *priv = usb_get_serial_port_data(port);
417 unsigned int control_state;
419 unsigned char last_lcr;
420 unsigned char last_msr;
422 /* Compensate for a hardware bug: although the Sitecom U232-P25
423 * device reports a maximum output packet size of 32 bytes,
424 * it seems to be able to accept only 16 bytes (and that's what
425 * SniffUSB says too...)
427 if (le16_to_cpu(serial->dev->descriptor.idProduct)
428 == MCT_U232_SITECOM_PID)
429 port->bulk_out_size = 16;
431 /* Do a defined restart: the normal serial device seems to
432 * always turn on DTR and RTS here, so do the same. I'm not
433 * sure if this is really necessary. But it should not harm
436 spin_lock_irqsave(&priv->lock, flags);
437 if (tty && C_BAUD(tty))
438 priv->control_state = TIOCM_DTR | TIOCM_RTS;
440 priv->control_state = 0;
442 priv->last_lcr = (MCT_U232_DATA_BITS_8 |
443 MCT_U232_PARITY_NONE |
444 MCT_U232_STOP_BITS_1);
445 control_state = priv->control_state;
446 last_lcr = priv->last_lcr;
447 spin_unlock_irqrestore(&priv->lock, flags);
448 mct_u232_set_modem_ctrl(port, control_state);
449 mct_u232_set_line_ctrl(port, last_lcr);
451 /* Read modem status and update control state */
452 mct_u232_get_modem_stat(port, &last_msr);
453 spin_lock_irqsave(&priv->lock, flags);
454 priv->last_msr = last_msr;
455 mct_u232_msr_to_state(port, &priv->control_state, priv->last_msr);
456 spin_unlock_irqrestore(&priv->lock, flags);
458 retval = usb_submit_urb(priv->read_urb, GFP_KERNEL);
461 "usb_submit_urb(read) failed pipe 0x%x err %d\n",
462 port->read_urb->pipe, retval);
466 retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
468 usb_kill_urb(priv->read_urb);
470 "usb_submit_urb(read int) failed pipe 0x%x err %d",
471 port->interrupt_in_urb->pipe, retval);
478 } /* mct_u232_open */
480 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on)
482 unsigned int control_state;
483 struct mct_u232_private *priv = usb_get_serial_port_data(port);
485 spin_lock_irq(&priv->lock);
487 priv->control_state |= TIOCM_DTR | TIOCM_RTS;
489 priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
490 control_state = priv->control_state;
491 spin_unlock_irq(&priv->lock);
493 mct_u232_set_modem_ctrl(port, control_state);
496 static void mct_u232_close(struct usb_serial_port *port)
498 struct mct_u232_private *priv = usb_get_serial_port_data(port);
500 usb_kill_urb(priv->read_urb);
501 usb_kill_urb(port->interrupt_in_urb);
503 usb_serial_generic_close(port);
504 } /* mct_u232_close */
507 static void mct_u232_read_int_callback(struct urb *urb)
509 struct usb_serial_port *port = urb->context;
510 struct mct_u232_private *priv = usb_get_serial_port_data(port);
511 unsigned char *data = urb->transfer_buffer;
513 int status = urb->status;
523 /* this urb is terminated, clean up */
524 dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
528 dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
533 usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
536 * Work-a-round: handle the 'usual' bulk-in pipe here
538 if (urb->transfer_buffer_length > 2) {
539 if (urb->actual_length) {
540 tty_insert_flip_string(&port->port, data,
542 tty_flip_buffer_push(&port->port);
548 * The interrupt-in pipe signals exceptional conditions (modem line
549 * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
551 spin_lock_irqsave(&priv->lock, flags);
552 priv->last_msr = data[MCT_U232_MSR_INDEX];
554 /* Record Control Line states */
555 mct_u232_msr_to_state(port, &priv->control_state, priv->last_msr);
557 mct_u232_msr_to_icount(&port->icount, priv->last_msr);
560 /* Not yet handled. See belkin_sa.c for further information */
561 /* Now to report any errors */
562 priv->last_lsr = data[MCT_U232_LSR_INDEX];
564 * fill in the flip buffer here, but I do not know the relation
565 * to the current/next receive buffer or characters. I need
566 * to look in to this before committing any code.
568 if (priv->last_lsr & MCT_U232_LSR_ERR) {
569 tty = tty_port_tty_get(&port->port);
571 if (priv->last_lsr & MCT_U232_LSR_OE) {
574 if (priv->last_lsr & MCT_U232_LSR_PE) {
577 if (priv->last_lsr & MCT_U232_LSR_FE) {
579 /* Break Indicator */
580 if (priv->last_lsr & MCT_U232_LSR_BI) {
585 wake_up_interruptible(&port->port.delta_msr_wait);
586 spin_unlock_irqrestore(&priv->lock, flags);
588 retval = usb_submit_urb(urb, GFP_ATOMIC);
591 "%s - usb_submit_urb failed with result %d\n",
593 } /* mct_u232_read_int_callback */
595 static void mct_u232_set_termios(struct tty_struct *tty,
596 struct usb_serial_port *port,
597 const struct ktermios *old_termios)
599 struct usb_serial *serial = port->serial;
600 struct mct_u232_private *priv = usb_get_serial_port_data(port);
601 struct ktermios *termios = &tty->termios;
602 unsigned int cflag = termios->c_cflag;
603 unsigned int old_cflag = old_termios->c_cflag;
605 unsigned int control_state;
606 unsigned char last_lcr;
608 /* get a local copy of the current port settings */
609 spin_lock_irqsave(&priv->lock, flags);
610 control_state = priv->control_state;
611 spin_unlock_irqrestore(&priv->lock, flags);
616 * Do not attempt to cache old rates and skip settings,
617 * disconnects screw such tricks up completely.
618 * Premature optimization is the root of all evil.
621 /* reassert DTR and RTS on transition from B0 */
622 if ((old_cflag & CBAUD) == B0) {
623 dev_dbg(&port->dev, "%s: baud was B0\n", __func__);
624 control_state |= TIOCM_DTR | TIOCM_RTS;
625 mct_u232_set_modem_ctrl(port, control_state);
628 mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty));
630 if ((cflag & CBAUD) == B0) {
631 dev_dbg(&port->dev, "%s: baud is B0\n", __func__);
632 /* Drop RTS and DTR */
633 control_state &= ~(TIOCM_DTR | TIOCM_RTS);
634 mct_u232_set_modem_ctrl(port, control_state);
638 * Update line control register (LCR)
643 last_lcr |= (cflag & PARODD) ?
644 MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
646 last_lcr |= MCT_U232_PARITY_NONE;
648 /* set the number of data bits */
649 switch (cflag & CSIZE) {
651 last_lcr |= MCT_U232_DATA_BITS_5; break;
653 last_lcr |= MCT_U232_DATA_BITS_6; break;
655 last_lcr |= MCT_U232_DATA_BITS_7; break;
657 last_lcr |= MCT_U232_DATA_BITS_8; break;
660 "CSIZE was not CS5-CS8, using default of 8\n");
661 last_lcr |= MCT_U232_DATA_BITS_8;
665 termios->c_cflag &= ~CMSPAR;
667 /* set the number of stop bits */
668 last_lcr |= (cflag & CSTOPB) ?
669 MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
671 mct_u232_set_line_ctrl(port, last_lcr);
673 /* save off the modified port settings */
674 spin_lock_irqsave(&priv->lock, flags);
675 priv->control_state = control_state;
676 priv->last_lcr = last_lcr;
677 spin_unlock_irqrestore(&priv->lock, flags);
678 } /* mct_u232_set_termios */
680 static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
682 struct usb_serial_port *port = tty->driver_data;
683 struct mct_u232_private *priv = usb_get_serial_port_data(port);
687 spin_lock_irqsave(&priv->lock, flags);
688 lcr = priv->last_lcr;
691 lcr |= MCT_U232_SET_BREAK;
692 spin_unlock_irqrestore(&priv->lock, flags);
694 mct_u232_set_line_ctrl(port, lcr);
695 } /* mct_u232_break_ctl */
698 static int mct_u232_tiocmget(struct tty_struct *tty)
700 struct usb_serial_port *port = tty->driver_data;
701 struct mct_u232_private *priv = usb_get_serial_port_data(port);
702 unsigned int control_state;
705 spin_lock_irqsave(&priv->lock, flags);
706 control_state = priv->control_state;
707 spin_unlock_irqrestore(&priv->lock, flags);
709 return control_state;
712 static int mct_u232_tiocmset(struct tty_struct *tty,
713 unsigned int set, unsigned int clear)
715 struct usb_serial_port *port = tty->driver_data;
716 struct mct_u232_private *priv = usb_get_serial_port_data(port);
717 unsigned int control_state;
720 spin_lock_irqsave(&priv->lock, flags);
721 control_state = priv->control_state;
724 control_state |= TIOCM_RTS;
726 control_state |= TIOCM_DTR;
727 if (clear & TIOCM_RTS)
728 control_state &= ~TIOCM_RTS;
729 if (clear & TIOCM_DTR)
730 control_state &= ~TIOCM_DTR;
732 priv->control_state = control_state;
733 spin_unlock_irqrestore(&priv->lock, flags);
734 return mct_u232_set_modem_ctrl(port, control_state);
737 static void mct_u232_throttle(struct tty_struct *tty)
739 struct usb_serial_port *port = tty->driver_data;
740 struct mct_u232_private *priv = usb_get_serial_port_data(port);
741 unsigned int control_state;
743 spin_lock_irq(&priv->lock);
744 priv->rx_flags |= THROTTLED;
745 if (C_CRTSCTS(tty)) {
746 priv->control_state &= ~TIOCM_RTS;
747 control_state = priv->control_state;
748 spin_unlock_irq(&priv->lock);
749 mct_u232_set_modem_ctrl(port, control_state);
751 spin_unlock_irq(&priv->lock);
755 static void mct_u232_unthrottle(struct tty_struct *tty)
757 struct usb_serial_port *port = tty->driver_data;
758 struct mct_u232_private *priv = usb_get_serial_port_data(port);
759 unsigned int control_state;
761 spin_lock_irq(&priv->lock);
762 if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
763 priv->rx_flags &= ~THROTTLED;
764 priv->control_state |= TIOCM_RTS;
765 control_state = priv->control_state;
766 spin_unlock_irq(&priv->lock);
767 mct_u232_set_modem_ctrl(port, control_state);
769 spin_unlock_irq(&priv->lock);
773 module_usb_serial_driver(serial_drivers, id_table);
775 MODULE_AUTHOR(DRIVER_AUTHOR);
776 MODULE_DESCRIPTION(DRIVER_DESC);
777 MODULE_LICENSE("GPL");