xref: /openbmc/linux/drivers/usb/serial/mct_u232.c (revision 96de0e252cedffad61b3cb5e05662c591898e69a)
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  * TEST STATUS:
24  *   Basic tests have been performed with minicom/zmodem transfers and
25  *   modem dialing under Linux 2.4.0-test10 (for me it works fine).
26  *
27  * 04-Nov-2003 Bill Marr <marr at flex dot com>
28  *   - Mimic Windows driver by sending 2 USB 'device request' messages
29  *     following normal 'baud rate change' message.  This allows data to be
30  *     transmitted to RS-232 devices which don't assert the 'CTS' signal.
31  *
32  * 10-Nov-2001 Wolfgang Grandegger
33  *   - Fixed an endianess problem with the baudrate selection for PowerPC.
34  *
35  * 06-Dec-2001 Martin Hamilton <martinh@gnu.org>
36  *	Added support for the Belkin F5U109 DB9 adaptor
37  *
38  * 30-May-2001 Greg Kroah-Hartman
39  *	switched from using spinlock to a semaphore, which fixes lots of problems.
40  *
41  * 04-May-2001 Stelian Pop
42  *   - Set the maximum bulk output size for Sitecom U232-P25 model to 16 bytes
43  *     instead of the device reported 32 (using 32 bytes causes many data
44  *     loss, Windows driver uses 16 too).
45  *
46  * 02-May-2001 Stelian Pop
47  *   - Fixed the baud calculation for Sitecom U232-P25 model
48  *
49  * 08-Apr-2001 gb
50  *   - Identify version on module load.
51  *
52  * 06-Jan-2001 Cornel Ciocirlan
53  *   - Added support for Sitecom U232-P25 model (Product Id 0x0230)
54  *   - Added support for D-Link DU-H3SP USB BAY (Product Id 0x0200)
55  *
56  * 29-Nov-2000 Greg Kroah-Hartman
57  *   - Added device id table to fit with 2.4.0-test11 structure.
58  *   - took out DEAL_WITH_TWO_INT_IN_ENDPOINTS #define as it's not needed
59  *     (lots of things will change if/when the usb-serial core changes to
60  *     handle these issues.
61  *
62  * 27-Nov-2000 Wolfgang Grandegger
63  *   A version for kernel 2.4.0-test10 released to the Linux community
64  *   (via linux-usb-devel).
65  */
66 
67 #include <linux/kernel.h>
68 #include <linux/errno.h>
69 #include <linux/init.h>
70 #include <linux/slab.h>
71 #include <linux/tty.h>
72 #include <linux/tty_driver.h>
73 #include <linux/tty_flip.h>
74 #include <linux/module.h>
75 #include <linux/spinlock.h>
76 #include <asm/uaccess.h>
77 #include <linux/usb.h>
78 #include <linux/usb/serial.h>
79 #include "mct_u232.h"
80 
81 /*
82  * Version Information
83  */
84 #define DRIVER_VERSION "z2.1"		/* Linux in-kernel version */
85 #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
86 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
87 
88 static int debug;
89 
90 /*
91  * Function prototypes
92  */
93 static int  mct_u232_startup	         (struct usb_serial *serial);
94 static void mct_u232_shutdown	         (struct usb_serial *serial);
95 static int  mct_u232_open	         (struct usb_serial_port *port,
96 					  struct file *filp);
97 static void mct_u232_close	         (struct usb_serial_port *port,
98 					  struct file *filp);
99 static void mct_u232_read_int_callback   (struct urb *urb);
100 static void mct_u232_set_termios         (struct usb_serial_port *port,
101 					  struct ktermios * old);
102 static int  mct_u232_ioctl	         (struct usb_serial_port *port,
103 					  struct file * file,
104 					  unsigned int cmd,
105 					  unsigned long arg);
106 static void mct_u232_break_ctl	         (struct usb_serial_port *port,
107 					  int break_state );
108 static int  mct_u232_tiocmget		 (struct usb_serial_port *port,
109 					  struct file *file);
110 static int  mct_u232_tiocmset		 (struct usb_serial_port *port,
111 					  struct file *file, unsigned int set,
112 					  unsigned int clear);
113 static void mct_u232_throttle		 (struct usb_serial_port *port);
114 static void mct_u232_unthrottle		 (struct usb_serial_port *port);
115 
116 
117 /*
118  * All of the device info needed for the MCT USB-RS232 converter.
119  */
120 static struct usb_device_id id_table_combined [] = {
121 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
122 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
123 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
124 	{ USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },
125 	{ }		/* Terminating entry */
126 };
127 
128 MODULE_DEVICE_TABLE (usb, id_table_combined);
129 
130 static struct usb_driver mct_u232_driver = {
131 	.name =		"mct_u232",
132 	.probe =	usb_serial_probe,
133 	.disconnect =	usb_serial_disconnect,
134 	.id_table =	id_table_combined,
135 	.no_dynamic_id = 	1,
136 };
137 
138 static struct usb_serial_driver mct_u232_device = {
139 	.driver = {
140 		.owner =	THIS_MODULE,
141 		.name =		"mct_u232",
142 	},
143 	.description =	     "MCT U232",
144 	.usb_driver = 	     &mct_u232_driver,
145 	.id_table =	     id_table_combined,
146 	.num_interrupt_in =  2,
147 	.num_bulk_in =	     0,
148 	.num_bulk_out =	     1,
149 	.num_ports =	     1,
150 	.open =		     mct_u232_open,
151 	.close =	     mct_u232_close,
152 	.throttle =	     mct_u232_throttle,
153 	.unthrottle =	     mct_u232_unthrottle,
154 	.read_int_callback = mct_u232_read_int_callback,
155 	.ioctl =	     mct_u232_ioctl,
156 	.set_termios =	     mct_u232_set_termios,
157 	.break_ctl =	     mct_u232_break_ctl,
158 	.tiocmget =	     mct_u232_tiocmget,
159 	.tiocmset =	     mct_u232_tiocmset,
160 	.attach =	     mct_u232_startup,
161 	.shutdown =	     mct_u232_shutdown,
162 };
163 
164 
165 struct mct_u232_private {
166 	spinlock_t lock;
167 	unsigned int	     control_state; /* Modem Line Setting (TIOCM) */
168 	unsigned char        last_lcr;      /* Line Control Register */
169 	unsigned char	     last_lsr;      /* Line Status Register */
170 	unsigned char	     last_msr;      /* Modem Status Register */
171 	unsigned int	     rx_flags;      /* Throttling flags */
172 };
173 
174 #define THROTTLED		0x01
175 
176 /*
177  * Handle vendor specific USB requests
178  */
179 
180 #define WDR_TIMEOUT 5000 /* default urb timeout */
181 
182 /*
183  * Later day 2.6.0-test kernels have new baud rates like B230400 which
184  * we do not know how to support. We ignore them for the moment.
185  * XXX Rate-limit the error message, it's user triggerable.
186  */
187 static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value)
188 {
189 	if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
190 	  || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
191 		switch (value) {
192 		case    300: return 0x01;
193 		case    600: return 0x02; /* this one not tested */
194 		case   1200: return 0x03;
195 		case   2400: return 0x04;
196 		case   4800: return 0x06;
197 		case   9600: return 0x08;
198 		case  19200: return 0x09;
199 		case  38400: return 0x0a;
200 		case  57600: return 0x0b;
201 		case 115200: return 0x0c;
202 		default:
203 			err("MCT USB-RS232: unsupported baudrate request 0x%x,"
204 			    " using default of B9600", value);
205 			return 0x08;
206 		}
207 	} else {
208 		switch (value) {
209 		case 300: break;
210 		case 600: break;
211 		case 1200: break;
212 		case 2400: break;
213 		case 4800: break;
214 		case 9600: break;
215 		case 19200: break;
216 		case 38400: break;
217 		case 57600: break;
218 		case 115200: break;
219 		default:
220 			err("MCT USB-RS232: unsupported baudrate request 0x%x,"
221 			    " using default of B9600", value);
222 			value = 9600;
223 		}
224 		return 115200/value;
225 	}
226 }
227 
228 static int mct_u232_set_baud_rate(struct usb_serial *serial, struct usb_serial_port *port,
229 				  speed_t value)
230 {
231 	__le32 divisor;
232         int rc;
233         unsigned char zero_byte = 0;
234         unsigned char cts_enable_byte = 0;
235 
236 	divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value));
237 
238         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
239                              MCT_U232_SET_BAUD_RATE_REQUEST,
240 			     MCT_U232_SET_REQUEST_TYPE,
241                              0, 0, &divisor, MCT_U232_SET_BAUD_RATE_SIZE,
242 			     WDR_TIMEOUT);
243 	if (rc < 0)
244 		err("Set BAUD RATE %d failed (error = %d)", value, rc);
245 	dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor);
246 
247 	/* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
248 	   always sends two extra USB 'device request' messages after the
249 	   'baud rate change' message.  The actual functionality of the
250 	   request codes in these messages is not fully understood but these
251 	   particular codes are never seen in any operation besides a baud
252 	   rate change.  Both of these messages send a single byte of data.
253 	   In the first message, the value of this byte is always zero.
254 
255 	   The second message has been determined experimentally to control
256 	   whether data will be transmitted to a device which is not asserting
257 	   the 'CTS' signal.  If the second message's data byte is zero, data
258 	   will be transmitted even if 'CTS' is not asserted (i.e. no hardware
259 	   flow control).  if the second message's data byte is nonzero (a value
260 	   of 1 is used by this driver), data will not be transmitted to a device
261 	   which is not asserting 'CTS'.
262 	*/
263 
264 	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
265 			     MCT_U232_SET_UNKNOWN1_REQUEST,
266 			     MCT_U232_SET_REQUEST_TYPE,
267 			     0, 0, &zero_byte, MCT_U232_SET_UNKNOWN1_SIZE,
268 			     WDR_TIMEOUT);
269 	if (rc < 0)
270 		err("Sending USB device request code %d failed (error = %d)",
271 		    MCT_U232_SET_UNKNOWN1_REQUEST, rc);
272 
273 	if (port && C_CRTSCTS(port->tty)) {
274 	   cts_enable_byte = 1;
275 	}
276 
277         dbg("set_baud_rate: send second control message, data = %02X", cts_enable_byte);
278 	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
279 			     MCT_U232_SET_CTS_REQUEST,
280 			     MCT_U232_SET_REQUEST_TYPE,
281 			     0, 0, &cts_enable_byte, MCT_U232_SET_CTS_SIZE,
282 			     WDR_TIMEOUT);
283 	if (rc < 0)
284 	  err("Sending USB device request code %d failed (error = %d)",
285 	      MCT_U232_SET_CTS_REQUEST, rc);
286 
287         return rc;
288 } /* mct_u232_set_baud_rate */
289 
290 static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr)
291 {
292         int rc;
293         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
294                              MCT_U232_SET_LINE_CTRL_REQUEST,
295 			     MCT_U232_SET_REQUEST_TYPE,
296                              0, 0, &lcr, MCT_U232_SET_LINE_CTRL_SIZE,
297 			     WDR_TIMEOUT);
298 	if (rc < 0)
299 		err("Set LINE CTRL 0x%x failed (error = %d)", lcr, rc);
300 	dbg("set_line_ctrl: 0x%x", lcr);
301         return rc;
302 } /* mct_u232_set_line_ctrl */
303 
304 static int mct_u232_set_modem_ctrl(struct usb_serial *serial,
305 				   unsigned int control_state)
306 {
307         int rc;
308 	unsigned char mcr = MCT_U232_MCR_NONE;
309 
310 	if (control_state & TIOCM_DTR)
311 		mcr |= MCT_U232_MCR_DTR;
312 	if (control_state & TIOCM_RTS)
313 		mcr |= MCT_U232_MCR_RTS;
314 
315         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
316                              MCT_U232_SET_MODEM_CTRL_REQUEST,
317 			     MCT_U232_SET_REQUEST_TYPE,
318                              0, 0, &mcr, MCT_U232_SET_MODEM_CTRL_SIZE,
319 			     WDR_TIMEOUT);
320 	if (rc < 0)
321 		err("Set MODEM CTRL 0x%x failed (error = %d)", mcr, rc);
322 	dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr);
323 
324         return rc;
325 } /* mct_u232_set_modem_ctrl */
326 
327 static int mct_u232_get_modem_stat(struct usb_serial *serial, unsigned char *msr)
328 {
329         int rc;
330         rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
331                              MCT_U232_GET_MODEM_STAT_REQUEST,
332 			     MCT_U232_GET_REQUEST_TYPE,
333                              0, 0, msr, MCT_U232_GET_MODEM_STAT_SIZE,
334 			     WDR_TIMEOUT);
335 	if (rc < 0) {
336 		err("Get MODEM STATus failed (error = %d)", rc);
337 		*msr = 0;
338 	}
339 	dbg("get_modem_stat: 0x%x", *msr);
340         return rc;
341 } /* mct_u232_get_modem_stat */
342 
343 static void mct_u232_msr_to_state(unsigned int *control_state, unsigned char msr)
344 {
345  	/* Translate Control Line states */
346 	if (msr & MCT_U232_MSR_DSR)
347 		*control_state |=  TIOCM_DSR;
348 	else
349 		*control_state &= ~TIOCM_DSR;
350 	if (msr & MCT_U232_MSR_CTS)
351 		*control_state |=  TIOCM_CTS;
352 	else
353 		*control_state &= ~TIOCM_CTS;
354 	if (msr & MCT_U232_MSR_RI)
355 		*control_state |=  TIOCM_RI;
356 	else
357 		*control_state &= ~TIOCM_RI;
358 	if (msr & MCT_U232_MSR_CD)
359 		*control_state |=  TIOCM_CD;
360 	else
361 		*control_state &= ~TIOCM_CD;
362  	dbg("msr_to_state: msr=0x%x ==> state=0x%x", msr, *control_state);
363 } /* mct_u232_msr_to_state */
364 
365 /*
366  * Driver's tty interface functions
367  */
368 
369 static int mct_u232_startup (struct usb_serial *serial)
370 {
371 	struct mct_u232_private *priv;
372 	struct usb_serial_port *port, *rport;
373 
374 	priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
375 	if (!priv)
376 		return -ENOMEM;
377 	spin_lock_init(&priv->lock);
378 	usb_set_serial_port_data(serial->port[0], priv);
379 
380 	init_waitqueue_head(&serial->port[0]->write_wait);
381 
382 	/* Puh, that's dirty */
383 	port = serial->port[0];
384 	rport = serial->port[1];
385 	/* No unlinking, it wasn't submitted yet. */
386 	usb_free_urb(port->read_urb);
387 	port->read_urb = rport->interrupt_in_urb;
388 	rport->interrupt_in_urb = NULL;
389 	port->read_urb->context = port;
390 
391 	return (0);
392 } /* mct_u232_startup */
393 
394 
395 static void mct_u232_shutdown (struct usb_serial *serial)
396 {
397 	struct mct_u232_private *priv;
398 	int i;
399 
400 	dbg("%s", __FUNCTION__);
401 
402 	for (i=0; i < serial->num_ports; ++i) {
403 		/* My special items, the standard routines free my urbs */
404 		priv = usb_get_serial_port_data(serial->port[i]);
405 		if (priv) {
406 			usb_set_serial_port_data(serial->port[i], NULL);
407 			kfree(priv);
408 		}
409 	}
410 } /* mct_u232_shutdown */
411 
412 static int  mct_u232_open (struct usb_serial_port *port, struct file *filp)
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 	dbg("%s port %d", __FUNCTION__, port->number);
423 
424 	/* Compensate for a hardware bug: although the Sitecom U232-P25
425 	 * device reports a maximum output packet size of 32 bytes,
426 	 * it seems to be able to accept only 16 bytes (and that's what
427 	 * SniffUSB says too...)
428 	 */
429 	if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID)
430 		port->bulk_out_size = 16;
431 
432 	/* Do a defined restart: the normal serial device seems to
433 	 * always turn on DTR and RTS here, so do the same. I'm not
434 	 * sure if this is really necessary. But it should not harm
435 	 * either.
436 	 */
437 	spin_lock_irqsave(&priv->lock, flags);
438 	if (port->tty->termios->c_cflag & CBAUD)
439 		priv->control_state = TIOCM_DTR | TIOCM_RTS;
440 	else
441 		priv->control_state = 0;
442 
443 	priv->last_lcr = (MCT_U232_DATA_BITS_8 |
444 			  MCT_U232_PARITY_NONE |
445 			  MCT_U232_STOP_BITS_1);
446 	control_state = priv->control_state;
447 	last_lcr = priv->last_lcr;
448 	spin_unlock_irqrestore(&priv->lock, flags);
449 	mct_u232_set_modem_ctrl(serial, control_state);
450 	mct_u232_set_line_ctrl(serial, last_lcr);
451 
452 	/* Read modem status and update control state */
453 	mct_u232_get_modem_stat(serial, &last_msr);
454 	spin_lock_irqsave(&priv->lock, flags);
455 	priv->last_msr = last_msr;
456 	mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
457 	spin_unlock_irqrestore(&priv->lock, flags);
458 
459 	port->read_urb->dev = port->serial->dev;
460 	retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
461 	if (retval) {
462 		err("usb_submit_urb(read bulk) failed pipe 0x%x err %d",
463 		    port->read_urb->pipe, retval);
464 		goto error;
465 	}
466 
467 	port->interrupt_in_urb->dev = port->serial->dev;
468 	retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
469 	if (retval) {
470 		usb_kill_urb(port->read_urb);
471 		err(" usb_submit_urb(read int) failed pipe 0x%x err %d",
472 		    port->interrupt_in_urb->pipe, retval);
473 		goto error;
474 	}
475 	return 0;
476 
477 error:
478 	return retval;
479 } /* mct_u232_open */
480 
481 
482 static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
483 {
484 	unsigned int c_cflag;
485 	unsigned long flags;
486 	unsigned int control_state;
487 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
488 	dbg("%s port %d", __FUNCTION__, port->number);
489 
490    	if (port->tty) {
491 		c_cflag = port->tty->termios->c_cflag;
492 		if (c_cflag & HUPCL) {
493 		   /* drop DTR and RTS */
494 		   spin_lock_irqsave(&priv->lock, flags);
495 		   priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
496 		   control_state = priv->control_state;
497 		   spin_unlock_irqrestore(&priv->lock, flags);
498 		   mct_u232_set_modem_ctrl(port->serial, control_state);
499 		}
500 	}
501 
502 
503 	if (port->serial->dev) {
504 		/* shutdown our urbs */
505 		usb_kill_urb(port->write_urb);
506 		usb_kill_urb(port->read_urb);
507 		usb_kill_urb(port->interrupt_in_urb);
508 	}
509 } /* mct_u232_close */
510 
511 
512 static void mct_u232_read_int_callback (struct urb *urb)
513 {
514 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
515 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
516 	struct usb_serial *serial = port->serial;
517 	struct tty_struct *tty;
518 	unsigned char *data = urb->transfer_buffer;
519 	int retval;
520 	int status = urb->status;
521 	unsigned long flags;
522 
523 	switch (status) {
524 	case 0:
525 		/* success */
526 		break;
527 	case -ECONNRESET:
528 	case -ENOENT:
529 	case -ESHUTDOWN:
530 		/* this urb is terminated, clean up */
531 		dbg("%s - urb shutting down with status: %d",
532 		    __FUNCTION__, status);
533 		return;
534 	default:
535 		dbg("%s - nonzero urb status received: %d",
536 		    __FUNCTION__, status);
537 		goto exit;
538 	}
539 
540 	if (!serial) {
541 		dbg("%s - bad serial pointer, exiting", __FUNCTION__);
542 		return;
543 	}
544 
545         dbg("%s - port %d", __FUNCTION__, port->number);
546 	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
547 
548 	/*
549 	 * Work-a-round: handle the 'usual' bulk-in pipe here
550 	 */
551 	if (urb->transfer_buffer_length > 2) {
552 		int i;
553 		tty = port->tty;
554 		if (urb->actual_length) {
555 			for (i = 0; i < urb->actual_length ; ++i) {
556 				tty_insert_flip_char(tty, data[i], 0);
557 			}
558 			tty_flip_buffer_push(tty);
559 		}
560 		goto exit;
561 	}
562 
563 	/*
564 	 * The interrupt-in pipe signals exceptional conditions (modem line
565 	 * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
566 	 */
567 	spin_lock_irqsave(&priv->lock, flags);
568 	priv->last_msr = data[MCT_U232_MSR_INDEX];
569 
570 	/* Record Control Line states */
571 	mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
572 
573 #if 0
574 	/* Not yet handled. See belin_sa.c for further information */
575 	/* Now to report any errors */
576 	priv->last_lsr = data[MCT_U232_LSR_INDEX];
577 	/*
578 	 * fill in the flip buffer here, but I do not know the relation
579 	 * to the current/next receive buffer or characters.  I need
580 	 * to look in to this before committing any code.
581 	 */
582 	if (priv->last_lsr & MCT_U232_LSR_ERR) {
583 		tty = port->tty;
584 		/* Overrun Error */
585 		if (priv->last_lsr & MCT_U232_LSR_OE) {
586 		}
587 		/* Parity Error */
588 		if (priv->last_lsr & MCT_U232_LSR_PE) {
589 		}
590 		/* Framing Error */
591 		if (priv->last_lsr & MCT_U232_LSR_FE) {
592 		}
593 		/* Break Indicator */
594 		if (priv->last_lsr & MCT_U232_LSR_BI) {
595 		}
596 	}
597 #endif
598 	spin_unlock_irqrestore(&priv->lock, flags);
599 exit:
600 	retval = usb_submit_urb (urb, GFP_ATOMIC);
601 	if (retval)
602 		err ("%s - usb_submit_urb failed with result %d",
603 		     __FUNCTION__, retval);
604 } /* mct_u232_read_int_callback */
605 
606 static void mct_u232_set_termios (struct usb_serial_port *port,
607 				  struct ktermios *old_termios)
608 {
609 	struct usb_serial *serial = port->serial;
610 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
611 	unsigned int cflag = port->tty->termios->c_cflag;
612 	unsigned int old_cflag = old_termios->c_cflag;
613 	unsigned long flags;
614 	unsigned int control_state;
615 	unsigned char last_lcr;
616 
617 	/* get a local copy of the current port settings */
618 	spin_lock_irqsave(&priv->lock, flags);
619 	control_state = priv->control_state;
620 	spin_unlock_irqrestore(&priv->lock, flags);
621 	last_lcr = 0;
622 
623 	/*
624 	 * Update baud rate.
625 	 * Do not attempt to cache old rates and skip settings,
626 	 * disconnects screw such tricks up completely.
627 	 * Premature optimization is the root of all evil.
628 	 */
629 
630         /* reassert DTR and RTS on transition from B0 */
631 	if ((old_cflag & CBAUD) == B0) {
632 		dbg("%s: baud was B0", __FUNCTION__);
633 		control_state |= TIOCM_DTR | TIOCM_RTS;
634 		mct_u232_set_modem_ctrl(serial, control_state);
635 	}
636 
637 	mct_u232_set_baud_rate(serial, port, tty_get_baud_rate(port->tty));
638 
639 	if ((cflag & CBAUD) == B0 ) {
640 		dbg("%s: baud is B0", __FUNCTION__);
641 		/* Drop RTS and DTR */
642 		control_state &= ~(TIOCM_DTR | TIOCM_RTS);
643        		mct_u232_set_modem_ctrl(serial, control_state);
644 	}
645 
646 	/*
647 	 * Update line control register (LCR)
648 	 */
649 
650 	/* set the parity */
651 	if (cflag & PARENB)
652 		last_lcr |= (cflag & PARODD) ?
653 			MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
654 	else
655 		last_lcr |= MCT_U232_PARITY_NONE;
656 
657 	/* set the number of data bits */
658 	switch (cflag & CSIZE) {
659 	case CS5:
660 		last_lcr |= MCT_U232_DATA_BITS_5; break;
661 	case CS6:
662 		last_lcr |= MCT_U232_DATA_BITS_6; break;
663 	case CS7:
664 		last_lcr |= MCT_U232_DATA_BITS_7; break;
665 	case CS8:
666 		last_lcr |= MCT_U232_DATA_BITS_8; break;
667 	default:
668 		err("CSIZE was not CS5-CS8, using default of 8");
669 		last_lcr |= MCT_U232_DATA_BITS_8;
670 		break;
671 	}
672 
673 	/* set the number of stop bits */
674 	last_lcr |= (cflag & CSTOPB) ?
675 		MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
676 
677 	mct_u232_set_line_ctrl(serial, last_lcr);
678 
679 	/* save off the modified port settings */
680 	spin_lock_irqsave(&priv->lock, flags);
681 	priv->control_state = control_state;
682 	priv->last_lcr = last_lcr;
683 	spin_unlock_irqrestore(&priv->lock, flags);
684 } /* mct_u232_set_termios */
685 
686 static void mct_u232_break_ctl( struct usb_serial_port *port, int break_state )
687 {
688 	struct usb_serial *serial = port->serial;
689 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
690 	unsigned char lcr;
691 	unsigned long flags;
692 
693 	dbg("%sstate=%d", __FUNCTION__, break_state);
694 
695 	spin_lock_irqsave(&priv->lock, flags);
696 	lcr = priv->last_lcr;
697 	spin_unlock_irqrestore(&priv->lock, flags);
698 
699 	if (break_state)
700 		lcr |= MCT_U232_SET_BREAK;
701 
702 	mct_u232_set_line_ctrl(serial, lcr);
703 } /* mct_u232_break_ctl */
704 
705 
706 static int mct_u232_tiocmget (struct usb_serial_port *port, struct file *file)
707 {
708 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
709 	unsigned int control_state;
710 	unsigned long flags;
711 
712 	dbg("%s", __FUNCTION__);
713 
714 	spin_lock_irqsave(&priv->lock, flags);
715 	control_state = priv->control_state;
716 	spin_unlock_irqrestore(&priv->lock, flags);
717 
718 	return control_state;
719 }
720 
721 static int mct_u232_tiocmset (struct usb_serial_port *port, struct file *file,
722 			      unsigned int set, unsigned int clear)
723 {
724 	struct usb_serial *serial = port->serial;
725 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
726 	unsigned int control_state;
727 	unsigned long flags;
728 
729 	dbg("%s", __FUNCTION__);
730 
731 	spin_lock_irqsave(&priv->lock, flags);
732 	control_state = priv->control_state;
733 
734 	if (set & TIOCM_RTS)
735 		control_state |= TIOCM_RTS;
736 	if (set & TIOCM_DTR)
737 		control_state |= TIOCM_DTR;
738 	if (clear & TIOCM_RTS)
739 		control_state &= ~TIOCM_RTS;
740 	if (clear & TIOCM_DTR)
741 		control_state &= ~TIOCM_DTR;
742 
743 	priv->control_state = control_state;
744 	spin_unlock_irqrestore(&priv->lock, flags);
745 	return mct_u232_set_modem_ctrl(serial, control_state);
746 }
747 
748 static int mct_u232_ioctl (struct usb_serial_port *port, struct file * file,
749 			   unsigned int cmd, unsigned long arg)
750 {
751 	dbg("%scmd=0x%x", __FUNCTION__, cmd);
752 
753 	/* Based on code from acm.c and others */
754 	switch (cmd) {
755 	case TIOCMIWAIT:
756 		/* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/
757 		/* TODO */
758 		return( 0 );
759 
760 	case TIOCGICOUNT:
761 		/* return count of modemline transitions */
762 		/* TODO */
763 		return 0;
764 
765 	default:
766 		dbg("%s: arg not supported - 0x%04x", __FUNCTION__,cmd);
767 		return(-ENOIOCTLCMD);
768 		break;
769 	}
770 	return 0;
771 } /* mct_u232_ioctl */
772 
773 static void mct_u232_throttle (struct usb_serial_port *port)
774 {
775 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
776 	unsigned long flags;
777 	unsigned int control_state;
778 	struct tty_struct *tty;
779 
780 	tty = port->tty;
781 	dbg("%s - port %d", __FUNCTION__, port->number);
782 
783 	spin_lock_irqsave(&priv->lock, flags);
784 	priv->rx_flags |= THROTTLED;
785 	if (C_CRTSCTS(tty)) {
786 	  priv->control_state &= ~TIOCM_RTS;
787 	  control_state = priv->control_state;
788 	  spin_unlock_irqrestore(&priv->lock, flags);
789 	  (void) mct_u232_set_modem_ctrl(port->serial, control_state);
790 	} else {
791 	  spin_unlock_irqrestore(&priv->lock, flags);
792 	}
793 }
794 
795 
796 static void mct_u232_unthrottle (struct usb_serial_port *port)
797 {
798 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
799 	unsigned long flags;
800 	unsigned int control_state;
801 	struct tty_struct *tty;
802 
803 	dbg("%s - port %d", __FUNCTION__, port->number);
804 
805 	tty = port->tty;
806 	spin_lock_irqsave(&priv->lock, flags);
807 	if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
808 	  priv->rx_flags &= ~THROTTLED;
809 	  priv->control_state |= TIOCM_RTS;
810 	  control_state = priv->control_state;
811 	  spin_unlock_irqrestore(&priv->lock, flags);
812 	  (void) mct_u232_set_modem_ctrl(port->serial, control_state);
813 	} else {
814 	  spin_unlock_irqrestore(&priv->lock, flags);
815 	}
816 }
817 
818 static int __init mct_u232_init (void)
819 {
820 	int retval;
821 	retval = usb_serial_register(&mct_u232_device);
822 	if (retval)
823 		goto failed_usb_serial_register;
824 	retval = usb_register(&mct_u232_driver);
825 	if (retval)
826 		goto failed_usb_register;
827 	info(DRIVER_DESC " " DRIVER_VERSION);
828 	return 0;
829 failed_usb_register:
830 	usb_serial_deregister(&mct_u232_device);
831 failed_usb_serial_register:
832 	return retval;
833 }
834 
835 
836 static void __exit mct_u232_exit (void)
837 {
838 	usb_deregister (&mct_u232_driver);
839 	usb_serial_deregister (&mct_u232_device);
840 }
841 
842 
843 module_init (mct_u232_init);
844 module_exit(mct_u232_exit);
845 
846 MODULE_AUTHOR( DRIVER_AUTHOR );
847 MODULE_DESCRIPTION( DRIVER_DESC );
848 MODULE_LICENSE("GPL");
849 
850 module_param(debug, bool, S_IRUGO | S_IWUSR);
851 MODULE_PARM_DESC(debug, "Debug enabled or not");
852