xref: /openbmc/linux/drivers/usb/serial/mct_u232.c (revision 020c5260)
1 /*
2  * MCT (Magic Control Technology Corp.) USB RS232 Converter Driver
3  *
4  *   Copyright (C) 2000 Wolfgang Grandegger (wolfgang@ces.ch)
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  * This program is largely derived from the Belkin USB Serial Adapter Driver
12  * (see belkin_sa.[ch]). All of the information about the device was acquired
13  * by using SniffUSB on Windows98. For technical details see mct_u232.h.
14  *
15  * William G. Greathouse and Greg Kroah-Hartman provided great help on how to
16  * do the reverse engineering and how to write a USB serial device driver.
17  *
18  * TO BE DONE, TO BE CHECKED:
19  *   DTR/RTS signal handling may be incomplete or incorrect. I have mainly
20  *   implemented what I have seen with SniffUSB or found in belkin_sa.c.
21  *   For further TODOs check also belkin_sa.c.
22  */
23 
24 #include <linux/kernel.h>
25 #include <linux/errno.h>
26 #include <linux/slab.h>
27 #include <linux/tty.h>
28 #include <linux/tty_driver.h>
29 #include <linux/tty_flip.h>
30 #include <linux/module.h>
31 #include <linux/spinlock.h>
32 #include <linux/uaccess.h>
33 #include <asm/unaligned.h>
34 #include <linux/usb.h>
35 #include <linux/usb/serial.h>
36 #include <linux/serial.h>
37 #include "mct_u232.h"
38 
39 #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
40 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
41 
42 /*
43  * Function prototypes
44  */
45 static int  mct_u232_port_probe(struct usb_serial_port *port);
46 static int  mct_u232_port_remove(struct usb_serial_port *remove);
47 static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);
48 static void mct_u232_close(struct usb_serial_port *port);
49 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on);
50 static void mct_u232_read_int_callback(struct urb *urb);
51 static void mct_u232_set_termios(struct tty_struct *tty,
52 			struct usb_serial_port *port, struct ktermios *old);
53 static void mct_u232_break_ctl(struct tty_struct *tty, int break_state);
54 static int  mct_u232_tiocmget(struct tty_struct *tty);
55 static int  mct_u232_tiocmset(struct tty_struct *tty,
56 			unsigned int set, unsigned int clear);
57 static void mct_u232_throttle(struct tty_struct *tty);
58 static void mct_u232_unthrottle(struct tty_struct *tty);
59 
60 
61 /*
62  * All of the device info needed for the MCT USB-RS232 converter.
63  */
64 static const struct usb_device_id id_table[] = {
65 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
66 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
67 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
68 	{ USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },
69 	{ }		/* Terminating entry */
70 };
71 MODULE_DEVICE_TABLE(usb, id_table);
72 
73 static struct usb_serial_driver mct_u232_device = {
74 	.driver = {
75 		.owner =	THIS_MODULE,
76 		.name =		"mct_u232",
77 	},
78 	.description =	     "MCT U232",
79 	.id_table =	     id_table,
80 	.num_ports =	     1,
81 	.open =		     mct_u232_open,
82 	.close =	     mct_u232_close,
83 	.dtr_rts =	     mct_u232_dtr_rts,
84 	.throttle =	     mct_u232_throttle,
85 	.unthrottle =	     mct_u232_unthrottle,
86 	.read_int_callback = mct_u232_read_int_callback,
87 	.set_termios =	     mct_u232_set_termios,
88 	.break_ctl =	     mct_u232_break_ctl,
89 	.tiocmget =	     mct_u232_tiocmget,
90 	.tiocmset =	     mct_u232_tiocmset,
91 	.tiocmiwait =        usb_serial_generic_tiocmiwait,
92 	.port_probe =        mct_u232_port_probe,
93 	.port_remove =       mct_u232_port_remove,
94 	.get_icount =        usb_serial_generic_get_icount,
95 };
96 
97 static struct usb_serial_driver * const serial_drivers[] = {
98 	&mct_u232_device, NULL
99 };
100 
101 struct mct_u232_private {
102 	struct urb *read_urb;
103 	spinlock_t lock;
104 	unsigned int	     control_state; /* Modem Line Setting (TIOCM) */
105 	unsigned char        last_lcr;      /* Line Control Register */
106 	unsigned char	     last_lsr;      /* Line Status Register */
107 	unsigned char	     last_msr;      /* Modem Status Register */
108 	unsigned int	     rx_flags;      /* Throttling flags */
109 };
110 
111 #define THROTTLED		0x01
112 
113 /*
114  * Handle vendor specific USB requests
115  */
116 
117 #define WDR_TIMEOUT 5000 /* default urb timeout */
118 
119 /*
120  * Later day 2.6.0-test kernels have new baud rates like B230400 which
121  * we do not know how to support. We ignore them for the moment.
122  */
123 static int mct_u232_calculate_baud_rate(struct usb_serial *serial,
124 					speed_t value, speed_t *result)
125 {
126 	*result = value;
127 
128 	if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
129 		|| le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
130 		switch (value) {
131 		case 300:
132 			return 0x01;
133 		case 600:
134 			return 0x02; /* this one not tested */
135 		case 1200:
136 			return 0x03;
137 		case 2400:
138 			return 0x04;
139 		case 4800:
140 			return 0x06;
141 		case 9600:
142 			return 0x08;
143 		case 19200:
144 			return 0x09;
145 		case 38400:
146 			return 0x0a;
147 		case 57600:
148 			return 0x0b;
149 		case 115200:
150 			return 0x0c;
151 		default:
152 			*result = 9600;
153 			return 0x08;
154 		}
155 	} else {
156 		/* FIXME: Can we use any divider - should we do
157 		   divider = 115200/value;
158 		   real baud = 115200/divider */
159 		switch (value) {
160 		case 300: break;
161 		case 600: break;
162 		case 1200: break;
163 		case 2400: break;
164 		case 4800: break;
165 		case 9600: break;
166 		case 19200: break;
167 		case 38400: break;
168 		case 57600: break;
169 		case 115200: break;
170 		default:
171 			value = 9600;
172 			*result = 9600;
173 		}
174 		return 115200/value;
175 	}
176 }
177 
178 static int mct_u232_set_baud_rate(struct tty_struct *tty,
179 	struct usb_serial *serial, struct usb_serial_port *port, speed_t value)
180 {
181 	unsigned int divisor;
182 	int rc;
183 	unsigned char *buf;
184 	unsigned char cts_enable_byte = 0;
185 	speed_t speed;
186 
187 	buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
188 	if (buf == NULL)
189 		return -ENOMEM;
190 
191 	divisor = mct_u232_calculate_baud_rate(serial, value, &speed);
192 	put_unaligned_le32(cpu_to_le32(divisor), buf);
193 	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
194 				MCT_U232_SET_BAUD_RATE_REQUEST,
195 				MCT_U232_SET_REQUEST_TYPE,
196 				0, 0, buf, MCT_U232_SET_BAUD_RATE_SIZE,
197 				WDR_TIMEOUT);
198 	if (rc < 0)	/*FIXME: What value speed results */
199 		dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n",
200 			value, rc);
201 	else
202 		tty_encode_baud_rate(tty, speed, speed);
203 	dev_dbg(&port->dev, "set_baud_rate: value: 0x%x, divisor: 0x%x\n", value, divisor);
204 
205 	/* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
206 	   always sends two extra USB 'device request' messages after the
207 	   'baud rate change' message.  The actual functionality of the
208 	   request codes in these messages is not fully understood but these
209 	   particular codes are never seen in any operation besides a baud
210 	   rate change.  Both of these messages send a single byte of data.
211 	   In the first message, the value of this byte is always zero.
212 
213 	   The second message has been determined experimentally to control
214 	   whether data will be transmitted to a device which is not asserting
215 	   the 'CTS' signal.  If the second message's data byte is zero, data
216 	   will be transmitted even if 'CTS' is not asserted (i.e. no hardware
217 	   flow control).  if the second message's data byte is nonzero (a
218 	   value of 1 is used by this driver), data will not be transmitted to
219 	   a device which is not asserting 'CTS'.
220 	*/
221 
222 	buf[0] = 0;
223 	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
224 				MCT_U232_SET_UNKNOWN1_REQUEST,
225 				MCT_U232_SET_REQUEST_TYPE,
226 				0, 0, buf, MCT_U232_SET_UNKNOWN1_SIZE,
227 				WDR_TIMEOUT);
228 	if (rc < 0)
229 		dev_err(&port->dev, "Sending USB device request code %d "
230 			"failed (error = %d)\n", MCT_U232_SET_UNKNOWN1_REQUEST,
231 			rc);
232 
233 	if (port && C_CRTSCTS(tty))
234 	   cts_enable_byte = 1;
235 
236 	dev_dbg(&port->dev, "set_baud_rate: send second control message, data = %02X\n",
237 		cts_enable_byte);
238 	buf[0] = cts_enable_byte;
239 	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
240 			MCT_U232_SET_CTS_REQUEST,
241 			MCT_U232_SET_REQUEST_TYPE,
242 			0, 0, buf, MCT_U232_SET_CTS_SIZE,
243 			WDR_TIMEOUT);
244 	if (rc < 0)
245 		dev_err(&port->dev, "Sending USB device request code %d "
246 			"failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc);
247 
248 	kfree(buf);
249 	return rc;
250 } /* mct_u232_set_baud_rate */
251 
252 static int mct_u232_set_line_ctrl(struct usb_serial_port *port,
253 				  unsigned char lcr)
254 {
255 	int rc;
256 	unsigned char *buf;
257 
258 	buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
259 	if (buf == NULL)
260 		return -ENOMEM;
261 
262 	buf[0] = lcr;
263 	rc = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
264 			MCT_U232_SET_LINE_CTRL_REQUEST,
265 			MCT_U232_SET_REQUEST_TYPE,
266 			0, 0, buf, MCT_U232_SET_LINE_CTRL_SIZE,
267 			WDR_TIMEOUT);
268 	if (rc < 0)
269 		dev_err(&port->dev, "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc);
270 	dev_dbg(&port->dev, "set_line_ctrl: 0x%x\n", lcr);
271 	kfree(buf);
272 	return rc;
273 } /* mct_u232_set_line_ctrl */
274 
275 static int mct_u232_set_modem_ctrl(struct usb_serial_port *port,
276 				   unsigned int control_state)
277 {
278 	int rc;
279 	unsigned char mcr;
280 	unsigned char *buf;
281 
282 	buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
283 	if (buf == NULL)
284 		return -ENOMEM;
285 
286 	mcr = MCT_U232_MCR_NONE;
287 	if (control_state & TIOCM_DTR)
288 		mcr |= MCT_U232_MCR_DTR;
289 	if (control_state & TIOCM_RTS)
290 		mcr |= MCT_U232_MCR_RTS;
291 
292 	buf[0] = mcr;
293 	rc = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
294 			MCT_U232_SET_MODEM_CTRL_REQUEST,
295 			MCT_U232_SET_REQUEST_TYPE,
296 			0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE,
297 			WDR_TIMEOUT);
298 	kfree(buf);
299 
300 	dev_dbg(&port->dev, "set_modem_ctrl: state=0x%x ==> mcr=0x%x\n", control_state, mcr);
301 
302 	if (rc < 0) {
303 		dev_err(&port->dev, "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc);
304 		return rc;
305 	}
306 	return 0;
307 } /* mct_u232_set_modem_ctrl */
308 
309 static int mct_u232_get_modem_stat(struct usb_serial_port *port,
310 				   unsigned char *msr)
311 {
312 	int rc;
313 	unsigned char *buf;
314 
315 	buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
316 	if (buf == NULL) {
317 		*msr = 0;
318 		return -ENOMEM;
319 	}
320 	rc = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0),
321 			MCT_U232_GET_MODEM_STAT_REQUEST,
322 			MCT_U232_GET_REQUEST_TYPE,
323 			0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE,
324 			WDR_TIMEOUT);
325 	if (rc < MCT_U232_GET_MODEM_STAT_SIZE) {
326 		dev_err(&port->dev, "Get MODEM STATus failed (error = %d)\n", rc);
327 
328 		if (rc >= 0)
329 			rc = -EIO;
330 
331 		*msr = 0;
332 	} else {
333 		*msr = buf[0];
334 	}
335 	dev_dbg(&port->dev, "get_modem_stat: 0x%x\n", *msr);
336 	kfree(buf);
337 	return rc;
338 } /* mct_u232_get_modem_stat */
339 
340 static void mct_u232_msr_to_icount(struct async_icount *icount,
341 						unsigned char msr)
342 {
343 	/* Translate Control Line states */
344 	if (msr & MCT_U232_MSR_DDSR)
345 		icount->dsr++;
346 	if (msr & MCT_U232_MSR_DCTS)
347 		icount->cts++;
348 	if (msr & MCT_U232_MSR_DRI)
349 		icount->rng++;
350 	if (msr & MCT_U232_MSR_DCD)
351 		icount->dcd++;
352 } /* mct_u232_msr_to_icount */
353 
354 static void mct_u232_msr_to_state(struct usb_serial_port *port,
355 				  unsigned int *control_state, unsigned char msr)
356 {
357 	/* Translate Control Line states */
358 	if (msr & MCT_U232_MSR_DSR)
359 		*control_state |=  TIOCM_DSR;
360 	else
361 		*control_state &= ~TIOCM_DSR;
362 	if (msr & MCT_U232_MSR_CTS)
363 		*control_state |=  TIOCM_CTS;
364 	else
365 		*control_state &= ~TIOCM_CTS;
366 	if (msr & MCT_U232_MSR_RI)
367 		*control_state |=  TIOCM_RI;
368 	else
369 		*control_state &= ~TIOCM_RI;
370 	if (msr & MCT_U232_MSR_CD)
371 		*control_state |=  TIOCM_CD;
372 	else
373 		*control_state &= ~TIOCM_CD;
374 	dev_dbg(&port->dev, "msr_to_state: msr=0x%x ==> state=0x%x\n", msr, *control_state);
375 } /* mct_u232_msr_to_state */
376 
377 /*
378  * Driver's tty interface functions
379  */
380 
381 static int mct_u232_port_probe(struct usb_serial_port *port)
382 {
383 	struct usb_serial *serial = port->serial;
384 	struct mct_u232_private *priv;
385 
386 	/* check first to simplify error handling */
387 	if (!serial->port[1] || !serial->port[1]->interrupt_in_urb) {
388 		dev_err(&port->dev, "expected endpoint missing\n");
389 		return -ENODEV;
390 	}
391 
392 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
393 	if (!priv)
394 		return -ENOMEM;
395 
396 	/* Use second interrupt-in endpoint for reading. */
397 	priv->read_urb = serial->port[1]->interrupt_in_urb;
398 	priv->read_urb->context = port;
399 
400 	spin_lock_init(&priv->lock);
401 
402 	usb_set_serial_port_data(port, priv);
403 
404 	return 0;
405 }
406 
407 static int mct_u232_port_remove(struct usb_serial_port *port)
408 {
409 	struct mct_u232_private *priv;
410 
411 	priv = usb_get_serial_port_data(port);
412 	kfree(priv);
413 
414 	return 0;
415 }
416 
417 static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
418 {
419 	struct usb_serial *serial = port->serial;
420 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
421 	int retval = 0;
422 	unsigned int control_state;
423 	unsigned long flags;
424 	unsigned char last_lcr;
425 	unsigned char last_msr;
426 
427 	/* Compensate for a hardware bug: although the Sitecom U232-P25
428 	 * device reports a maximum output packet size of 32 bytes,
429 	 * it seems to be able to accept only 16 bytes (and that's what
430 	 * SniffUSB says too...)
431 	 */
432 	if (le16_to_cpu(serial->dev->descriptor.idProduct)
433 						== MCT_U232_SITECOM_PID)
434 		port->bulk_out_size = 16;
435 
436 	/* Do a defined restart: the normal serial device seems to
437 	 * always turn on DTR and RTS here, so do the same. I'm not
438 	 * sure if this is really necessary. But it should not harm
439 	 * either.
440 	 */
441 	spin_lock_irqsave(&priv->lock, flags);
442 	if (tty && C_BAUD(tty))
443 		priv->control_state = TIOCM_DTR | TIOCM_RTS;
444 	else
445 		priv->control_state = 0;
446 
447 	priv->last_lcr = (MCT_U232_DATA_BITS_8 |
448 			  MCT_U232_PARITY_NONE |
449 			  MCT_U232_STOP_BITS_1);
450 	control_state = priv->control_state;
451 	last_lcr = priv->last_lcr;
452 	spin_unlock_irqrestore(&priv->lock, flags);
453 	mct_u232_set_modem_ctrl(port, control_state);
454 	mct_u232_set_line_ctrl(port, last_lcr);
455 
456 	/* Read modem status and update control state */
457 	mct_u232_get_modem_stat(port, &last_msr);
458 	spin_lock_irqsave(&priv->lock, flags);
459 	priv->last_msr = last_msr;
460 	mct_u232_msr_to_state(port, &priv->control_state, priv->last_msr);
461 	spin_unlock_irqrestore(&priv->lock, flags);
462 
463 	retval = usb_submit_urb(priv->read_urb, GFP_KERNEL);
464 	if (retval) {
465 		dev_err(&port->dev,
466 			"usb_submit_urb(read) failed pipe 0x%x err %d\n",
467 			port->read_urb->pipe, retval);
468 		goto error;
469 	}
470 
471 	retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
472 	if (retval) {
473 		usb_kill_urb(priv->read_urb);
474 		dev_err(&port->dev,
475 			"usb_submit_urb(read int) failed pipe 0x%x err %d",
476 			port->interrupt_in_urb->pipe, retval);
477 		goto error;
478 	}
479 	return 0;
480 
481 error:
482 	return retval;
483 } /* mct_u232_open */
484 
485 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on)
486 {
487 	unsigned int control_state;
488 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
489 
490 	spin_lock_irq(&priv->lock);
491 	if (on)
492 		priv->control_state |= TIOCM_DTR | TIOCM_RTS;
493 	else
494 		priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
495 	control_state = priv->control_state;
496 	spin_unlock_irq(&priv->lock);
497 
498 	mct_u232_set_modem_ctrl(port, control_state);
499 }
500 
501 static void mct_u232_close(struct usb_serial_port *port)
502 {
503 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
504 
505 	usb_kill_urb(priv->read_urb);
506 	usb_kill_urb(port->interrupt_in_urb);
507 
508 	usb_serial_generic_close(port);
509 } /* mct_u232_close */
510 
511 
512 static void mct_u232_read_int_callback(struct urb *urb)
513 {
514 	struct usb_serial_port *port = urb->context;
515 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
516 	unsigned char *data = urb->transfer_buffer;
517 	int retval;
518 	int status = urb->status;
519 	unsigned long flags;
520 
521 	switch (status) {
522 	case 0:
523 		/* success */
524 		break;
525 	case -ECONNRESET:
526 	case -ENOENT:
527 	case -ESHUTDOWN:
528 		/* this urb is terminated, clean up */
529 		dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
530 			__func__, status);
531 		return;
532 	default:
533 		dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
534 			__func__, status);
535 		goto exit;
536 	}
537 
538 	usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
539 
540 	/*
541 	 * Work-a-round: handle the 'usual' bulk-in pipe here
542 	 */
543 	if (urb->transfer_buffer_length > 2) {
544 		if (urb->actual_length) {
545 			tty_insert_flip_string(&port->port, data,
546 					urb->actual_length);
547 			tty_flip_buffer_push(&port->port);
548 		}
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 				 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 void 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 	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