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