xref: /openbmc/linux/drivers/usb/serial/mct_u232.c (revision cf1788fb)
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 <asm/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 		.owner =	THIS_MODULE,
73 		.name =		"mct_u232",
74 	},
75 	.description =	     "MCT U232",
76 	.id_table =	     id_table,
77 	.num_ports =	     1,
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,
92 };
93 
94 static struct usb_serial_driver * const serial_drivers[] = {
95 	&mct_u232_device, NULL
96 };
97 
98 struct mct_u232_private {
99 	struct urb *read_urb;
100 	spinlock_t lock;
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 */
106 };
107 
108 #define THROTTLED		0x01
109 
110 /*
111  * Handle vendor specific USB requests
112  */
113 
114 #define WDR_TIMEOUT 5000 /* default urb timeout */
115 
116 /*
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.
119  */
120 static int mct_u232_calculate_baud_rate(struct usb_serial *serial,
121 					speed_t value, speed_t *result)
122 {
123 	*result = value;
124 
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) {
127 		switch (value) {
128 		case 300:
129 			return 0x01;
130 		case 600:
131 			return 0x02; /* this one not tested */
132 		case 1200:
133 			return 0x03;
134 		case 2400:
135 			return 0x04;
136 		case 4800:
137 			return 0x06;
138 		case 9600:
139 			return 0x08;
140 		case 19200:
141 			return 0x09;
142 		case 38400:
143 			return 0x0a;
144 		case 57600:
145 			return 0x0b;
146 		case 115200:
147 			return 0x0c;
148 		default:
149 			*result = 9600;
150 			return 0x08;
151 		}
152 	} else {
153 		/* FIXME: Can we use any divider - should we do
154 		   divider = 115200/value;
155 		   real baud = 115200/divider */
156 		switch (value) {
157 		case 300: break;
158 		case 600: break;
159 		case 1200: break;
160 		case 2400: break;
161 		case 4800: break;
162 		case 9600: break;
163 		case 19200: break;
164 		case 38400: break;
165 		case 57600: break;
166 		case 115200: break;
167 		default:
168 			value = 9600;
169 			*result = 9600;
170 		}
171 		return 115200/value;
172 	}
173 }
174 
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)
177 {
178 	unsigned int divisor;
179 	int rc;
180 	unsigned char *buf;
181 	unsigned char cts_enable_byte = 0;
182 	speed_t speed;
183 
184 	buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
185 	if (buf == NULL)
186 		return -ENOMEM;
187 
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,
194 				WDR_TIMEOUT);
195 	if (rc < 0)	/*FIXME: What value speed results */
196 		dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n",
197 			value, rc);
198 	else
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);
201 
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.
209 
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'.
217 	*/
218 
219 	buf[0] = 0;
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,
224 				WDR_TIMEOUT);
225 	if (rc < 0)
226 		dev_err(&port->dev, "Sending USB device request code %d "
227 			"failed (error = %d)\n", MCT_U232_SET_UNKNOWN1_REQUEST,
228 			rc);
229 
230 	if (port && C_CRTSCTS(tty))
231 	   cts_enable_byte = 1;
232 
233 	dev_dbg(&port->dev, "set_baud_rate: send second control message, data = %02X\n",
234 		cts_enable_byte);
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,
240 			WDR_TIMEOUT);
241 	if (rc < 0)
242 		dev_err(&port->dev, "Sending USB device request code %d "
243 			"failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc);
244 
245 	kfree(buf);
246 	return rc;
247 } /* mct_u232_set_baud_rate */
248 
249 static int mct_u232_set_line_ctrl(struct usb_serial_port *port,
250 				  unsigned char lcr)
251 {
252 	int rc;
253 	unsigned char *buf;
254 
255 	buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
256 	if (buf == NULL)
257 		return -ENOMEM;
258 
259 	buf[0] = lcr;
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,
264 			WDR_TIMEOUT);
265 	if (rc < 0)
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);
268 	kfree(buf);
269 	return rc;
270 } /* mct_u232_set_line_ctrl */
271 
272 static int mct_u232_set_modem_ctrl(struct usb_serial_port *port,
273 				   unsigned int control_state)
274 {
275 	int rc;
276 	unsigned char mcr;
277 	unsigned char *buf;
278 
279 	buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
280 	if (buf == NULL)
281 		return -ENOMEM;
282 
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;
288 
289 	buf[0] = mcr;
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,
294 			WDR_TIMEOUT);
295 	kfree(buf);
296 
297 	dev_dbg(&port->dev, "set_modem_ctrl: state=0x%x ==> mcr=0x%x\n", control_state, mcr);
298 
299 	if (rc < 0) {
300 		dev_err(&port->dev, "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc);
301 		return rc;
302 	}
303 	return 0;
304 } /* mct_u232_set_modem_ctrl */
305 
306 static int mct_u232_get_modem_stat(struct usb_serial_port *port,
307 				   unsigned char *msr)
308 {
309 	int rc;
310 	unsigned char *buf;
311 
312 	buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
313 	if (buf == NULL) {
314 		*msr = 0;
315 		return -ENOMEM;
316 	}
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,
321 			WDR_TIMEOUT);
322 	if (rc < MCT_U232_GET_MODEM_STAT_SIZE) {
323 		dev_err(&port->dev, "Get MODEM STATus failed (error = %d)\n", rc);
324 
325 		if (rc >= 0)
326 			rc = -EIO;
327 
328 		*msr = 0;
329 	} else {
330 		*msr = buf[0];
331 	}
332 	dev_dbg(&port->dev, "get_modem_stat: 0x%x\n", *msr);
333 	kfree(buf);
334 	return rc;
335 } /* mct_u232_get_modem_stat */
336 
337 static void mct_u232_msr_to_icount(struct async_icount *icount,
338 						unsigned char msr)
339 {
340 	/* Translate Control Line states */
341 	if (msr & MCT_U232_MSR_DDSR)
342 		icount->dsr++;
343 	if (msr & MCT_U232_MSR_DCTS)
344 		icount->cts++;
345 	if (msr & MCT_U232_MSR_DRI)
346 		icount->rng++;
347 	if (msr & MCT_U232_MSR_DCD)
348 		icount->dcd++;
349 } /* mct_u232_msr_to_icount */
350 
351 static void mct_u232_msr_to_state(struct usb_serial_port *port,
352 				  unsigned int *control_state, unsigned char msr)
353 {
354 	/* Translate Control Line states */
355 	if (msr & MCT_U232_MSR_DSR)
356 		*control_state |=  TIOCM_DSR;
357 	else
358 		*control_state &= ~TIOCM_DSR;
359 	if (msr & MCT_U232_MSR_CTS)
360 		*control_state |=  TIOCM_CTS;
361 	else
362 		*control_state &= ~TIOCM_CTS;
363 	if (msr & MCT_U232_MSR_RI)
364 		*control_state |=  TIOCM_RI;
365 	else
366 		*control_state &= ~TIOCM_RI;
367 	if (msr & MCT_U232_MSR_CD)
368 		*control_state |=  TIOCM_CD;
369 	else
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 */
373 
374 /*
375  * Driver's tty interface functions
376  */
377 
378 static int mct_u232_port_probe(struct usb_serial_port *port)
379 {
380 	struct usb_serial *serial = port->serial;
381 	struct mct_u232_private *priv;
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 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
390 	if (!priv)
391 		return -ENOMEM;
392 
393 	/* Use second interrupt-in endpoint for reading. */
394 	priv->read_urb = serial->port[1]->interrupt_in_urb;
395 	priv->read_urb->context = port;
396 
397 	spin_lock_init(&priv->lock);
398 
399 	usb_set_serial_port_data(port, priv);
400 
401 	return 0;
402 }
403 
404 static void mct_u232_port_remove(struct usb_serial_port *port)
405 {
406 	struct mct_u232_private *priv;
407 
408 	priv = usb_get_serial_port_data(port);
409 	kfree(priv);
410 }
411 
412 static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
413 {
414 	struct usb_serial *serial = port->serial;
415 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
416 	int retval = 0;
417 	unsigned int control_state;
418 	unsigned long flags;
419 	unsigned char last_lcr;
420 	unsigned char last_msr;
421 
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...)
426 	 */
427 	if (le16_to_cpu(serial->dev->descriptor.idProduct)
428 						== MCT_U232_SITECOM_PID)
429 		port->bulk_out_size = 16;
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 	/*
548 	 * The interrupt-in pipe signals exceptional conditions (modem line
549 	 * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
550 	 */
551 	spin_lock_irqsave(&priv->lock, flags);
552 	priv->last_msr = data[MCT_U232_MSR_INDEX];
553 
554 	/* Record Control Line states */
555 	mct_u232_msr_to_state(port, &priv->control_state, priv->last_msr);
556 
557 	mct_u232_msr_to_icount(&port->icount, priv->last_msr);
558 
559 #if 0
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];
563 	/*
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.
567 	 */
568 	if (priv->last_lsr & MCT_U232_LSR_ERR) {
569 		tty = tty_port_tty_get(&port->port);
570 		/* Overrun Error */
571 		if (priv->last_lsr & MCT_U232_LSR_OE) {
572 		}
573 		/* Parity Error */
574 		if (priv->last_lsr & MCT_U232_LSR_PE) {
575 		}
576 		/* Framing Error */
577 		if (priv->last_lsr & MCT_U232_LSR_FE) {
578 		}
579 		/* Break Indicator */
580 		if (priv->last_lsr & MCT_U232_LSR_BI) {
581 		}
582 		tty_kref_put(tty);
583 	}
584 #endif
585 	wake_up_interruptible(&port->port.delta_msr_wait);
586 	spin_unlock_irqrestore(&priv->lock, flags);
587 exit:
588 	retval = usb_submit_urb(urb, GFP_ATOMIC);
589 	if (retval)
590 		dev_err(&port->dev,
591 			"%s - usb_submit_urb failed with result %d\n",
592 			__func__, retval);
593 } /* mct_u232_read_int_callback */
594 
595 static void mct_u232_set_termios(struct tty_struct *tty,
596 				 struct usb_serial_port *port,
597 				 const struct ktermios *old_termios)
598 {
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;
604 	unsigned long flags;
605 	unsigned int control_state;
606 	unsigned char last_lcr;
607 
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);
612 	last_lcr = 0;
613 
614 	/*
615 	 * Update baud rate.
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.
619 	 */
620 
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);
626 	}
627 
628 	mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty));
629 
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);
635 	}
636 
637 	/*
638 	 * Update line control register (LCR)
639 	 */
640 
641 	/* set the parity */
642 	if (cflag & PARENB)
643 		last_lcr |= (cflag & PARODD) ?
644 			MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
645 	else
646 		last_lcr |= MCT_U232_PARITY_NONE;
647 
648 	/* set the number of data bits */
649 	switch (cflag & CSIZE) {
650 	case CS5:
651 		last_lcr |= MCT_U232_DATA_BITS_5; break;
652 	case CS6:
653 		last_lcr |= MCT_U232_DATA_BITS_6; break;
654 	case CS7:
655 		last_lcr |= MCT_U232_DATA_BITS_7; break;
656 	case CS8:
657 		last_lcr |= MCT_U232_DATA_BITS_8; break;
658 	default:
659 		dev_err(&port->dev,
660 			"CSIZE was not CS5-CS8, using default of 8\n");
661 		last_lcr |= MCT_U232_DATA_BITS_8;
662 		break;
663 	}
664 
665 	termios->c_cflag &= ~CMSPAR;
666 
667 	/* set the number of stop bits */
668 	last_lcr |= (cflag & CSTOPB) ?
669 		MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
670 
671 	mct_u232_set_line_ctrl(port, last_lcr);
672 
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 */
679 
680 static int mct_u232_break_ctl(struct tty_struct *tty, int break_state)
681 {
682 	struct usb_serial_port *port = tty->driver_data;
683 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
684 	unsigned char lcr;
685 	unsigned long flags;
686 
687 	spin_lock_irqsave(&priv->lock, flags);
688 	lcr = priv->last_lcr;
689 
690 	if (break_state)
691 		lcr |= MCT_U232_SET_BREAK;
692 	spin_unlock_irqrestore(&priv->lock, flags);
693 
694 	return mct_u232_set_line_ctrl(port, lcr);
695 } /* mct_u232_break_ctl */
696 
697 
698 static int mct_u232_tiocmget(struct tty_struct *tty)
699 {
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;
703 	unsigned long flags;
704 
705 	spin_lock_irqsave(&priv->lock, flags);
706 	control_state = priv->control_state;
707 	spin_unlock_irqrestore(&priv->lock, flags);
708 
709 	return control_state;
710 }
711 
712 static int mct_u232_tiocmset(struct tty_struct *tty,
713 			      unsigned int set, unsigned int clear)
714 {
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;
718 	unsigned long flags;
719 
720 	spin_lock_irqsave(&priv->lock, flags);
721 	control_state = priv->control_state;
722 
723 	if (set & TIOCM_RTS)
724 		control_state |= TIOCM_RTS;
725 	if (set & TIOCM_DTR)
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;
731 
732 	priv->control_state = control_state;
733 	spin_unlock_irqrestore(&priv->lock, flags);
734 	return mct_u232_set_modem_ctrl(port, control_state);
735 }
736 
737 static void mct_u232_throttle(struct tty_struct *tty)
738 {
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;
742 
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);
750 	} else {
751 		spin_unlock_irq(&priv->lock);
752 	}
753 }
754 
755 static void mct_u232_unthrottle(struct tty_struct *tty)
756 {
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;
760 
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);
768 	} else {
769 		spin_unlock_irq(&priv->lock);
770 	}
771 }
772 
773 module_usb_serial_driver(serial_drivers, id_table);
774 
775 MODULE_AUTHOR(DRIVER_AUTHOR);
776 MODULE_DESCRIPTION(DRIVER_DESC);
777 MODULE_LICENSE("GPL");
778