xref: /linux/drivers/usb/serial/mct_u232.c (revision 513480da5e9c8f55b4f8f5e89f386e26188fbb3f)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * MCT (Magic Control Technology Corp.) USB RS232 Converter Driver
4  *
5  *   Copyright (C) 2000 Wolfgang Grandegger (wolfgang@ces.ch)
6  *
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.
10  *
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.
13  *
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.
18  */
19 
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 <linux/unaligned.h>
30 #include <linux/usb.h>
31 #include <linux/usb/serial.h>
32 #include <linux/serial.h>
33 #include "mct_u232.h"
34 
35 #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
36 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
37 
38 /*
39  * Function prototypes
40  */
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 int  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);
56 
57 
58 /*
59  * All of the device info needed for the MCT USB-RS232 converter.
60  */
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 */
67 };
68 MODULE_DEVICE_TABLE(usb, id_table);
69 
70 static struct usb_serial_driver mct_u232_device = {
71 	.driver = {
72 		.name =		"mct_u232",
73 	},
74 	.description =	     "MCT U232",
75 	.id_table =	     id_table,
76 	.num_ports =	     1,
77 	.open =		     mct_u232_open,
78 	.close =	     mct_u232_close,
79 	.dtr_rts =	     mct_u232_dtr_rts,
80 	.throttle =	     mct_u232_throttle,
81 	.unthrottle =	     mct_u232_unthrottle,
82 	.read_int_callback = mct_u232_read_int_callback,
83 	.set_termios =	     mct_u232_set_termios,
84 	.break_ctl =	     mct_u232_break_ctl,
85 	.tiocmget =	     mct_u232_tiocmget,
86 	.tiocmset =	     mct_u232_tiocmset,
87 	.tiocmiwait =        usb_serial_generic_tiocmiwait,
88 	.port_probe =        mct_u232_port_probe,
89 	.port_remove =       mct_u232_port_remove,
90 	.get_icount =        usb_serial_generic_get_icount,
91 };
92 
93 static struct usb_serial_driver * const serial_drivers[] = {
94 	&mct_u232_device, NULL
95 };
96 
97 struct mct_u232_private {
98 	struct urb *read_urb;
99 	spinlock_t lock;
100 	unsigned int	     control_state; /* Modem Line Setting (TIOCM) */
101 	unsigned char        last_lcr;      /* Line Control Register */
102 	unsigned char	     last_lsr;      /* Line Status Register */
103 	unsigned char	     last_msr;      /* Modem Status Register */
104 	unsigned int	     rx_flags;      /* Throttling flags */
105 };
106 
107 #define THROTTLED		0x01
108 
109 /*
110  * Handle vendor specific USB requests
111  */
112 
113 #define WDR_TIMEOUT 5000 /* default urb timeout */
114 
115 /*
116  * Later day 2.6.0-test kernels have new baud rates like B230400 which
117  * we do not know how to support. We ignore them for the moment.
118  */
119 static int mct_u232_calculate_baud_rate(struct usb_serial *serial,
120 					speed_t value, speed_t *result)
121 {
122 	*result = value;
123 
124 	if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
125 		|| le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
126 		switch (value) {
127 		case 300:
128 			return 0x01;
129 		case 600:
130 			return 0x02; /* this one not tested */
131 		case 1200:
132 			return 0x03;
133 		case 2400:
134 			return 0x04;
135 		case 4800:
136 			return 0x06;
137 		case 9600:
138 			return 0x08;
139 		case 19200:
140 			return 0x09;
141 		case 38400:
142 			return 0x0a;
143 		case 57600:
144 			return 0x0b;
145 		case 115200:
146 			return 0x0c;
147 		default:
148 			*result = 9600;
149 			return 0x08;
150 		}
151 	} else {
152 		/* FIXME: Can we use any divider - should we do
153 		   divider = 115200/value;
154 		   real baud = 115200/divider */
155 		switch (value) {
156 		case 300: break;
157 		case 600: break;
158 		case 1200: break;
159 		case 2400: break;
160 		case 4800: break;
161 		case 9600: break;
162 		case 19200: break;
163 		case 38400: break;
164 		case 57600: break;
165 		case 115200: break;
166 		default:
167 			value = 9600;
168 			*result = 9600;
169 		}
170 		return 115200/value;
171 	}
172 }
173 
174 static int mct_u232_set_baud_rate(struct tty_struct *tty,
175 	struct usb_serial *serial, struct usb_serial_port *port, speed_t value)
176 {
177 	unsigned int divisor;
178 	int rc;
179 	unsigned char *buf;
180 	unsigned char cts_enable_byte = 0;
181 	speed_t speed;
182 
183 	buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
184 	if (buf == NULL)
185 		return -ENOMEM;
186 
187 	divisor = mct_u232_calculate_baud_rate(serial, value, &speed);
188 	put_unaligned_le32(divisor, buf);
189 	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
190 				MCT_U232_SET_BAUD_RATE_REQUEST,
191 				MCT_U232_SET_REQUEST_TYPE,
192 				0, 0, buf, MCT_U232_SET_BAUD_RATE_SIZE,
193 				WDR_TIMEOUT);
194 	if (rc < 0)	/*FIXME: What value speed results */
195 		dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n",
196 			value, rc);
197 	else
198 		tty_encode_baud_rate(tty, speed, speed);
199 	dev_dbg(&port->dev, "set_baud_rate: value: 0x%x, divisor: 0x%x\n", value, divisor);
200 
201 	/* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
202 	   always sends two extra USB 'device request' messages after the
203 	   'baud rate change' message.  The actual functionality of the
204 	   request codes in these messages is not fully understood but these
205 	   particular codes are never seen in any operation besides a baud
206 	   rate change.  Both of these messages send a single byte of data.
207 	   In the first message, the value of this byte is always zero.
208 
209 	   The second message has been determined experimentally to control
210 	   whether data will be transmitted to a device which is not asserting
211 	   the 'CTS' signal.  If the second message's data byte is zero, data
212 	   will be transmitted even if 'CTS' is not asserted (i.e. no hardware
213 	   flow control).  if the second message's data byte is nonzero (a
214 	   value of 1 is used by this driver), data will not be transmitted to
215 	   a device which is not asserting 'CTS'.
216 	*/
217 
218 	buf[0] = 0;
219 	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
220 				MCT_U232_SET_UNKNOWN1_REQUEST,
221 				MCT_U232_SET_REQUEST_TYPE,
222 				0, 0, buf, MCT_U232_SET_UNKNOWN1_SIZE,
223 				WDR_TIMEOUT);
224 	if (rc < 0)
225 		dev_err(&port->dev, "Sending USB device request code %d "
226 			"failed (error = %d)\n", MCT_U232_SET_UNKNOWN1_REQUEST,
227 			rc);
228 
229 	if (port && C_CRTSCTS(tty))
230 	   cts_enable_byte = 1;
231 
232 	dev_dbg(&port->dev, "set_baud_rate: send second control message, data = %02X\n",
233 		cts_enable_byte);
234 	buf[0] = cts_enable_byte;
235 	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
236 			MCT_U232_SET_CTS_REQUEST,
237 			MCT_U232_SET_REQUEST_TYPE,
238 			0, 0, buf, MCT_U232_SET_CTS_SIZE,
239 			WDR_TIMEOUT);
240 	if (rc < 0)
241 		dev_err(&port->dev, "Sending USB device request code %d "
242 			"failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc);
243 
244 	kfree(buf);
245 	return rc;
246 } /* mct_u232_set_baud_rate */
247 
248 static int mct_u232_set_line_ctrl(struct usb_serial_port *port,
249 				  unsigned char lcr)
250 {
251 	int rc;
252 	unsigned char *buf;
253 
254 	buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
255 	if (buf == NULL)
256 		return -ENOMEM;
257 
258 	buf[0] = lcr;
259 	rc = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
260 			MCT_U232_SET_LINE_CTRL_REQUEST,
261 			MCT_U232_SET_REQUEST_TYPE,
262 			0, 0, buf, MCT_U232_SET_LINE_CTRL_SIZE,
263 			WDR_TIMEOUT);
264 	if (rc < 0)
265 		dev_err(&port->dev, "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc);
266 	dev_dbg(&port->dev, "set_line_ctrl: 0x%x\n", lcr);
267 	kfree(buf);
268 	return rc;
269 } /* mct_u232_set_line_ctrl */
270 
271 static int mct_u232_set_modem_ctrl(struct usb_serial_port *port,
272 				   unsigned int control_state)
273 {
274 	int rc;
275 	unsigned char mcr;
276 	unsigned char *buf;
277 
278 	buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
279 	if (buf == NULL)
280 		return -ENOMEM;
281 
282 	mcr = MCT_U232_MCR_NONE;
283 	if (control_state & TIOCM_DTR)
284 		mcr |= MCT_U232_MCR_DTR;
285 	if (control_state & TIOCM_RTS)
286 		mcr |= MCT_U232_MCR_RTS;
287 
288 	buf[0] = mcr;
289 	rc = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
290 			MCT_U232_SET_MODEM_CTRL_REQUEST,
291 			MCT_U232_SET_REQUEST_TYPE,
292 			0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE,
293 			WDR_TIMEOUT);
294 	kfree(buf);
295 
296 	dev_dbg(&port->dev, "set_modem_ctrl: state=0x%x ==> mcr=0x%x\n", control_state, mcr);
297 
298 	if (rc < 0) {
299 		dev_err(&port->dev, "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc);
300 		return rc;
301 	}
302 	return 0;
303 } /* mct_u232_set_modem_ctrl */
304 
305 static int mct_u232_get_modem_stat(struct usb_serial_port *port,
306 				   unsigned char *msr)
307 {
308 	int rc;
309 	unsigned char *buf;
310 
311 	buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
312 	if (buf == NULL) {
313 		*msr = 0;
314 		return -ENOMEM;
315 	}
316 	rc = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0),
317 			MCT_U232_GET_MODEM_STAT_REQUEST,
318 			MCT_U232_GET_REQUEST_TYPE,
319 			0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE,
320 			WDR_TIMEOUT);
321 	if (rc < MCT_U232_GET_MODEM_STAT_SIZE) {
322 		dev_err(&port->dev, "Get MODEM STATus failed (error = %d)\n", rc);
323 
324 		if (rc >= 0)
325 			rc = -EIO;
326 
327 		*msr = 0;
328 	} else {
329 		*msr = buf[0];
330 	}
331 	dev_dbg(&port->dev, "get_modem_stat: 0x%x\n", *msr);
332 	kfree(buf);
333 	return rc;
334 } /* mct_u232_get_modem_stat */
335 
336 static void mct_u232_msr_to_icount(struct async_icount *icount,
337 						unsigned char msr)
338 {
339 	/* Translate Control Line states */
340 	if (msr & MCT_U232_MSR_DDSR)
341 		icount->dsr++;
342 	if (msr & MCT_U232_MSR_DCTS)
343 		icount->cts++;
344 	if (msr & MCT_U232_MSR_DRI)
345 		icount->rng++;
346 	if (msr & MCT_U232_MSR_DCD)
347 		icount->dcd++;
348 } /* mct_u232_msr_to_icount */
349 
350 static void mct_u232_msr_to_state(struct usb_serial_port *port,
351 				  unsigned int *control_state, unsigned char msr)
352 {
353 	/* Translate Control Line states */
354 	if (msr & MCT_U232_MSR_DSR)
355 		*control_state |=  TIOCM_DSR;
356 	else
357 		*control_state &= ~TIOCM_DSR;
358 	if (msr & MCT_U232_MSR_CTS)
359 		*control_state |=  TIOCM_CTS;
360 	else
361 		*control_state &= ~TIOCM_CTS;
362 	if (msr & MCT_U232_MSR_RI)
363 		*control_state |=  TIOCM_RI;
364 	else
365 		*control_state &= ~TIOCM_RI;
366 	if (msr & MCT_U232_MSR_CD)
367 		*control_state |=  TIOCM_CD;
368 	else
369 		*control_state &= ~TIOCM_CD;
370 	dev_dbg(&port->dev, "msr_to_state: msr=0x%x ==> state=0x%x\n", msr, *control_state);
371 } /* mct_u232_msr_to_state */
372 
373 /*
374  * Driver's tty interface functions
375  */
376 
377 static int mct_u232_port_probe(struct usb_serial_port *port)
378 {
379 	struct usb_serial *serial = port->serial;
380 	struct mct_u232_private *priv;
381 	u16 pid;
382 
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");
386 		return -ENODEV;
387 	}
388 
389 	/*
390 	 * Compensate for a hardware bug: although the Sitecom U232-P25
391 	 * device reports a maximum output packet size of 32 bytes,
392 	 * it seems to be able to accept only 16 bytes (and that's what
393 	 * SniffUSB says too...)
394 	 */
395 	pid = le16_to_cpu(serial->dev->descriptor.idProduct);
396 	if (pid == MCT_U232_SITECOM_PID)
397 		port->bulk_out_size = min(16, port->bulk_out_size);
398 
399 	priv = kzalloc_obj(*priv);
400 	if (!priv)
401 		return -ENOMEM;
402 
403 	/* Use second interrupt-in endpoint for reading. */
404 	priv->read_urb = serial->port[1]->interrupt_in_urb;
405 	priv->read_urb->context = port;
406 
407 	spin_lock_init(&priv->lock);
408 
409 	usb_set_serial_port_data(port, priv);
410 
411 	return 0;
412 }
413 
414 static void mct_u232_port_remove(struct usb_serial_port *port)
415 {
416 	struct mct_u232_private *priv;
417 
418 	priv = usb_get_serial_port_data(port);
419 	kfree(priv);
420 }
421 
422 static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
423 {
424 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
425 	int retval = 0;
426 	unsigned int control_state;
427 	unsigned long flags;
428 	unsigned char last_lcr;
429 	unsigned char last_msr;
430 
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
434 	 * either.
435 	 */
436 	spin_lock_irqsave(&priv->lock, flags);
437 	if (tty && C_BAUD(tty))
438 		priv->control_state = TIOCM_DTR | TIOCM_RTS;
439 	else
440 		priv->control_state = 0;
441 
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);
450 
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);
457 
458 	retval = usb_submit_urb(priv->read_urb, GFP_KERNEL);
459 	if (retval) {
460 		dev_err(&port->dev,
461 			"usb_submit_urb(read) failed pipe 0x%x err %d\n",
462 			port->read_urb->pipe, retval);
463 		goto error;
464 	}
465 
466 	retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
467 	if (retval) {
468 		usb_kill_urb(priv->read_urb);
469 		dev_err(&port->dev,
470 			"usb_submit_urb(read int) failed pipe 0x%x err %d",
471 			port->interrupt_in_urb->pipe, retval);
472 		goto error;
473 	}
474 	return 0;
475 
476 error:
477 	return retval;
478 } /* mct_u232_open */
479 
480 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on)
481 {
482 	unsigned int control_state;
483 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
484 
485 	spin_lock_irq(&priv->lock);
486 	if (on)
487 		priv->control_state |= TIOCM_DTR | TIOCM_RTS;
488 	else
489 		priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
490 	control_state = priv->control_state;
491 	spin_unlock_irq(&priv->lock);
492 
493 	mct_u232_set_modem_ctrl(port, control_state);
494 }
495 
496 static void mct_u232_close(struct usb_serial_port *port)
497 {
498 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
499 
500 	usb_kill_urb(priv->read_urb);
501 	usb_kill_urb(port->interrupt_in_urb);
502 
503 	usb_serial_generic_close(port);
504 } /* mct_u232_close */
505 
506 
507 static void mct_u232_read_int_callback(struct urb *urb)
508 {
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;
512 	int retval;
513 	int status = urb->status;
514 	unsigned long flags;
515 
516 	switch (status) {
517 	case 0:
518 		/* success */
519 		break;
520 	case -ECONNRESET:
521 	case -ENOENT:
522 	case -ESHUTDOWN:
523 		/* this urb is terminated, clean up */
524 		dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
525 			__func__, status);
526 		return;
527 	default:
528 		dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
529 			__func__, status);
530 		goto exit;
531 	}
532 
533 	usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
534 
535 	/*
536 	 * Work-a-round: handle the 'usual' bulk-in pipe here
537 	 */
538 	if (urb->transfer_buffer_length > 2) {
539 		if (urb->actual_length) {
540 			tty_insert_flip_string(&port->port, data,
541 					urb->actual_length);
542 			tty_flip_buffer_push(&port->port);
543 		}
544 		goto exit;
545 	}
546 
547 	if (urb->actual_length < 2) {
548 		dev_warn_ratelimited(&port->dev, "short interrupt-in packet\n");
549 		goto exit;
550 	}
551 
552 	/*
553 	 * The interrupt-in pipe signals exceptional conditions (modem line
554 	 * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
555 	 */
556 	spin_lock_irqsave(&priv->lock, flags);
557 	priv->last_msr = data[MCT_U232_MSR_INDEX];
558 
559 	/* Record Control Line states */
560 	mct_u232_msr_to_state(port, &priv->control_state, priv->last_msr);
561 
562 	mct_u232_msr_to_icount(&port->icount, priv->last_msr);
563 
564 #if 0
565 	/* Not yet handled. See belkin_sa.c for further information */
566 	/* Now to report any errors */
567 	priv->last_lsr = data[MCT_U232_LSR_INDEX];
568 	/*
569 	 * fill in the flip buffer here, but I do not know the relation
570 	 * to the current/next receive buffer or characters.  I need
571 	 * to look in to this before committing any code.
572 	 */
573 	if (priv->last_lsr & MCT_U232_LSR_ERR) {
574 		tty = tty_port_tty_get(&port->port);
575 		/* Overrun Error */
576 		if (priv->last_lsr & MCT_U232_LSR_OE) {
577 		}
578 		/* Parity Error */
579 		if (priv->last_lsr & MCT_U232_LSR_PE) {
580 		}
581 		/* Framing Error */
582 		if (priv->last_lsr & MCT_U232_LSR_FE) {
583 		}
584 		/* Break Indicator */
585 		if (priv->last_lsr & MCT_U232_LSR_BI) {
586 		}
587 		tty_kref_put(tty);
588 	}
589 #endif
590 	wake_up_interruptible(&port->port.delta_msr_wait);
591 	spin_unlock_irqrestore(&priv->lock, flags);
592 exit:
593 	retval = usb_submit_urb(urb, GFP_ATOMIC);
594 	if (retval)
595 		dev_err(&port->dev,
596 			"%s - usb_submit_urb failed with result %d\n",
597 			__func__, retval);
598 } /* mct_u232_read_int_callback */
599 
600 static void mct_u232_set_termios(struct tty_struct *tty,
601 				 struct usb_serial_port *port,
602 				 const struct ktermios *old_termios)
603 {
604 	struct usb_serial *serial = port->serial;
605 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
606 	struct ktermios *termios = &tty->termios;
607 	unsigned int cflag = termios->c_cflag;
608 	unsigned int old_cflag = old_termios->c_cflag;
609 	unsigned long flags;
610 	unsigned int control_state;
611 	unsigned char last_lcr;
612 
613 	/* get a local copy of the current port settings */
614 	spin_lock_irqsave(&priv->lock, flags);
615 	control_state = priv->control_state;
616 	spin_unlock_irqrestore(&priv->lock, flags);
617 	last_lcr = 0;
618 
619 	/*
620 	 * Update baud rate.
621 	 * Do not attempt to cache old rates and skip settings,
622 	 * disconnects screw such tricks up completely.
623 	 * Premature optimization is the root of all evil.
624 	 */
625 
626 	/* reassert DTR and RTS on transition from B0 */
627 	if ((old_cflag & CBAUD) == B0) {
628 		dev_dbg(&port->dev, "%s: baud was B0\n", __func__);
629 		control_state |= TIOCM_DTR | TIOCM_RTS;
630 		mct_u232_set_modem_ctrl(port, control_state);
631 	}
632 
633 	mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty));
634 
635 	if ((cflag & CBAUD) == B0) {
636 		dev_dbg(&port->dev, "%s: baud is B0\n", __func__);
637 		/* Drop RTS and DTR */
638 		control_state &= ~(TIOCM_DTR | TIOCM_RTS);
639 		mct_u232_set_modem_ctrl(port, control_state);
640 	}
641 
642 	/*
643 	 * Update line control register (LCR)
644 	 */
645 
646 	/* set the parity */
647 	if (cflag & PARENB)
648 		last_lcr |= (cflag & PARODD) ?
649 			MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
650 	else
651 		last_lcr |= MCT_U232_PARITY_NONE;
652 
653 	/* set the number of data bits */
654 	switch (cflag & CSIZE) {
655 	case CS5:
656 		last_lcr |= MCT_U232_DATA_BITS_5; break;
657 	case CS6:
658 		last_lcr |= MCT_U232_DATA_BITS_6; break;
659 	case CS7:
660 		last_lcr |= MCT_U232_DATA_BITS_7; break;
661 	case CS8:
662 		last_lcr |= MCT_U232_DATA_BITS_8; break;
663 	default:
664 		dev_err(&port->dev,
665 			"CSIZE was not CS5-CS8, using default of 8\n");
666 		last_lcr |= MCT_U232_DATA_BITS_8;
667 		break;
668 	}
669 
670 	termios->c_cflag &= ~CMSPAR;
671 
672 	/* set the number of stop bits */
673 	last_lcr |= (cflag & CSTOPB) ?
674 		MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
675 
676 	mct_u232_set_line_ctrl(port, last_lcr);
677 
678 	/* save off the modified port settings */
679 	spin_lock_irqsave(&priv->lock, flags);
680 	priv->control_state = control_state;
681 	priv->last_lcr = last_lcr;
682 	spin_unlock_irqrestore(&priv->lock, flags);
683 } /* mct_u232_set_termios */
684 
685 static int mct_u232_break_ctl(struct tty_struct *tty, int break_state)
686 {
687 	struct usb_serial_port *port = tty->driver_data;
688 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
689 	unsigned char lcr;
690 	unsigned long flags;
691 
692 	spin_lock_irqsave(&priv->lock, flags);
693 	lcr = priv->last_lcr;
694 
695 	if (break_state)
696 		lcr |= MCT_U232_SET_BREAK;
697 	spin_unlock_irqrestore(&priv->lock, flags);
698 
699 	return mct_u232_set_line_ctrl(port, lcr);
700 } /* mct_u232_break_ctl */
701 
702 
703 static int mct_u232_tiocmget(struct tty_struct *tty)
704 {
705 	struct usb_serial_port *port = tty->driver_data;
706 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
707 	unsigned int control_state;
708 	unsigned long flags;
709 
710 	spin_lock_irqsave(&priv->lock, flags);
711 	control_state = priv->control_state;
712 	spin_unlock_irqrestore(&priv->lock, flags);
713 
714 	return control_state;
715 }
716 
717 static int mct_u232_tiocmset(struct tty_struct *tty,
718 			      unsigned int set, unsigned int clear)
719 {
720 	struct usb_serial_port *port = tty->driver_data;
721 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
722 	unsigned int control_state;
723 	unsigned long flags;
724 
725 	spin_lock_irqsave(&priv->lock, flags);
726 	control_state = priv->control_state;
727 
728 	if (set & TIOCM_RTS)
729 		control_state |= TIOCM_RTS;
730 	if (set & TIOCM_DTR)
731 		control_state |= TIOCM_DTR;
732 	if (clear & TIOCM_RTS)
733 		control_state &= ~TIOCM_RTS;
734 	if (clear & TIOCM_DTR)
735 		control_state &= ~TIOCM_DTR;
736 
737 	priv->control_state = control_state;
738 	spin_unlock_irqrestore(&priv->lock, flags);
739 	return mct_u232_set_modem_ctrl(port, control_state);
740 }
741 
742 static void mct_u232_throttle(struct tty_struct *tty)
743 {
744 	struct usb_serial_port *port = tty->driver_data;
745 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
746 	unsigned int control_state;
747 
748 	spin_lock_irq(&priv->lock);
749 	priv->rx_flags |= THROTTLED;
750 	if (C_CRTSCTS(tty)) {
751 		priv->control_state &= ~TIOCM_RTS;
752 		control_state = priv->control_state;
753 		spin_unlock_irq(&priv->lock);
754 		mct_u232_set_modem_ctrl(port, control_state);
755 	} else {
756 		spin_unlock_irq(&priv->lock);
757 	}
758 }
759 
760 static void mct_u232_unthrottle(struct tty_struct *tty)
761 {
762 	struct usb_serial_port *port = tty->driver_data;
763 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
764 	unsigned int control_state;
765 
766 	spin_lock_irq(&priv->lock);
767 	if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
768 		priv->rx_flags &= ~THROTTLED;
769 		priv->control_state |= TIOCM_RTS;
770 		control_state = priv->control_state;
771 		spin_unlock_irq(&priv->lock);
772 		mct_u232_set_modem_ctrl(port, control_state);
773 	} else {
774 		spin_unlock_irq(&priv->lock);
775 	}
776 }
777 
778 module_usb_serial_driver(serial_drivers, id_table);
779 
780 MODULE_AUTHOR(DRIVER_AUTHOR);
781 MODULE_DESCRIPTION(DRIVER_DESC);
782 MODULE_LICENSE("GPL");
783