1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
44
45static int mct_u232_port_probe(struct usb_serial_port *port);
46static int mct_u232_port_remove(struct usb_serial_port *remove);
47static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);
48static void mct_u232_close(struct usb_serial_port *port);
49static void mct_u232_dtr_rts(struct usb_serial_port *port, int on);
50static void mct_u232_read_int_callback(struct urb *urb);
51static void mct_u232_set_termios(struct tty_struct *tty,
52 struct usb_serial_port *port, struct ktermios *old);
53static void mct_u232_break_ctl(struct tty_struct *tty, int break_state);
54static int mct_u232_tiocmget(struct tty_struct *tty);
55static int mct_u232_tiocmset(struct tty_struct *tty,
56 unsigned int set, unsigned int clear);
57static void mct_u232_throttle(struct tty_struct *tty);
58static void mct_u232_unthrottle(struct tty_struct *tty);
59
60
61
62
63
64static 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 { }
70};
71MODULE_DEVICE_TABLE(usb, id_table);
72
73static 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
97static struct usb_serial_driver * const serial_drivers[] = {
98 &mct_u232_device, NULL
99};
100
101struct mct_u232_private {
102 struct urb *read_urb;
103 spinlock_t lock;
104 unsigned int control_state;
105 unsigned char last_lcr;
106 unsigned char last_lsr;
107 unsigned char last_msr;
108 unsigned int rx_flags;
109};
110
111#define THROTTLED 0x01
112
113
114
115
116
117#define WDR_TIMEOUT 5000
118
119
120
121
122
123static 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;
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
157
158
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
178static 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)
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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
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}
251
252static 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}
274
275static 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}
308
309static 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 < 0) {
326 dev_err(&port->dev, "Get MODEM STATus failed (error = %d)\n", rc);
327 *msr = 0;
328 } else {
329 *msr = buf[0];
330 }
331 dev_dbg(&port->dev, "get_modem_stat: 0x%x\n", *msr);
332 kfree(buf);
333 return rc;
334}
335
336static void mct_u232_msr_to_icount(struct async_icount *icount,
337 unsigned char msr)
338{
339
340 if (msr & MCT_U232_MSR_DDSR)
341 icount->dsr++;
342 if (msr & MCT_U232_MSR_DCTS)
343 icount->cts++;
344 if (msr & MCT_U232_MSR_DRI)
345 icount->rng++;
346 if (msr & MCT_U232_MSR_DCD)
347 icount->dcd++;
348}
349
350static void mct_u232_msr_to_state(struct usb_serial_port *port,
351 unsigned int *control_state, unsigned char msr)
352{
353
354 if (msr & MCT_U232_MSR_DSR)
355 *control_state |= TIOCM_DSR;
356 else
357 *control_state &= ~TIOCM_DSR;
358 if (msr & MCT_U232_MSR_CTS)
359 *control_state |= TIOCM_CTS;
360 else
361 *control_state &= ~TIOCM_CTS;
362 if (msr & MCT_U232_MSR_RI)
363 *control_state |= TIOCM_RI;
364 else
365 *control_state &= ~TIOCM_RI;
366 if (msr & MCT_U232_MSR_CD)
367 *control_state |= TIOCM_CD;
368 else
369 *control_state &= ~TIOCM_CD;
370 dev_dbg(&port->dev, "msr_to_state: msr=0x%x ==> state=0x%x\n", msr, *control_state);
371}
372
373
374
375
376
377static int mct_u232_port_probe(struct usb_serial_port *port)
378{
379 struct mct_u232_private *priv;
380
381 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
382 if (!priv)
383 return -ENOMEM;
384
385
386 priv->read_urb = port->serial->port[1]->interrupt_in_urb;
387 priv->read_urb->context = port;
388
389 spin_lock_init(&priv->lock);
390
391 usb_set_serial_port_data(port, priv);
392
393 return 0;
394}
395
396static int mct_u232_port_remove(struct usb_serial_port *port)
397{
398 struct mct_u232_private *priv;
399
400 priv = usb_get_serial_port_data(port);
401 kfree(priv);
402
403 return 0;
404}
405
406static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
407{
408 struct usb_serial *serial = port->serial;
409 struct mct_u232_private *priv = usb_get_serial_port_data(port);
410 int retval = 0;
411 unsigned int control_state;
412 unsigned long flags;
413 unsigned char last_lcr;
414 unsigned char last_msr;
415
416
417
418
419
420
421 if (le16_to_cpu(serial->dev->descriptor.idProduct)
422 == MCT_U232_SITECOM_PID)
423 port->bulk_out_size = 16;
424
425
426
427
428
429
430 spin_lock_irqsave(&priv->lock, flags);
431 if (tty && (tty->termios.c_cflag & CBAUD))
432 priv->control_state = TIOCM_DTR | TIOCM_RTS;
433 else
434 priv->control_state = 0;
435
436 priv->last_lcr = (MCT_U232_DATA_BITS_8 |
437 MCT_U232_PARITY_NONE |
438 MCT_U232_STOP_BITS_1);
439 control_state = priv->control_state;
440 last_lcr = priv->last_lcr;
441 spin_unlock_irqrestore(&priv->lock, flags);
442 mct_u232_set_modem_ctrl(port, control_state);
443 mct_u232_set_line_ctrl(port, last_lcr);
444
445
446 mct_u232_get_modem_stat(port, &last_msr);
447 spin_lock_irqsave(&priv->lock, flags);
448 priv->last_msr = last_msr;
449 mct_u232_msr_to_state(port, &priv->control_state, priv->last_msr);
450 spin_unlock_irqrestore(&priv->lock, flags);
451
452 retval = usb_submit_urb(priv->read_urb, GFP_KERNEL);
453 if (retval) {
454 dev_err(&port->dev,
455 "usb_submit_urb(read) failed pipe 0x%x err %d\n",
456 port->read_urb->pipe, retval);
457 goto error;
458 }
459
460 retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
461 if (retval) {
462 usb_kill_urb(priv->read_urb);
463 dev_err(&port->dev,
464 "usb_submit_urb(read int) failed pipe 0x%x err %d",
465 port->interrupt_in_urb->pipe, retval);
466 goto error;
467 }
468 return 0;
469
470error:
471 return retval;
472}
473
474static void mct_u232_dtr_rts(struct usb_serial_port *port, int on)
475{
476 unsigned int control_state;
477 struct mct_u232_private *priv = usb_get_serial_port_data(port);
478
479 spin_lock_irq(&priv->lock);
480 if (on)
481 priv->control_state |= TIOCM_DTR | TIOCM_RTS;
482 else
483 priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
484 control_state = priv->control_state;
485 spin_unlock_irq(&priv->lock);
486
487 mct_u232_set_modem_ctrl(port, control_state);
488}
489
490static void mct_u232_close(struct usb_serial_port *port)
491{
492 struct mct_u232_private *priv = usb_get_serial_port_data(port);
493
494 usb_kill_urb(priv->read_urb);
495 usb_kill_urb(port->interrupt_in_urb);
496
497 usb_serial_generic_close(port);
498}
499
500
501static void mct_u232_read_int_callback(struct urb *urb)
502{
503 struct usb_serial_port *port = urb->context;
504 struct mct_u232_private *priv = usb_get_serial_port_data(port);
505 unsigned char *data = urb->transfer_buffer;
506 int retval;
507 int status = urb->status;
508 unsigned long flags;
509
510 switch (status) {
511 case 0:
512
513 break;
514 case -ECONNRESET:
515 case -ENOENT:
516 case -ESHUTDOWN:
517
518 dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
519 __func__, status);
520 return;
521 default:
522 dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
523 __func__, status);
524 goto exit;
525 }
526
527 usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
528
529
530
531
532 if (urb->transfer_buffer_length > 2) {
533 if (urb->actual_length) {
534 tty_insert_flip_string(&port->port, data,
535 urb->actual_length);
536 tty_flip_buffer_push(&port->port);
537 }
538 goto exit;
539 }
540
541
542
543
544
545 spin_lock_irqsave(&priv->lock, flags);
546 priv->last_msr = data[MCT_U232_MSR_INDEX];
547
548
549 mct_u232_msr_to_state(port, &priv->control_state, priv->last_msr);
550
551 mct_u232_msr_to_icount(&port->icount, priv->last_msr);
552
553#if 0
554
555
556 priv->last_lsr = data[MCT_U232_LSR_INDEX];
557
558
559
560
561
562 if (priv->last_lsr & MCT_U232_LSR_ERR) {
563 tty = tty_port_tty_get(&port->port);
564
565 if (priv->last_lsr & MCT_U232_LSR_OE) {
566 }
567
568 if (priv->last_lsr & MCT_U232_LSR_PE) {
569 }
570
571 if (priv->last_lsr & MCT_U232_LSR_FE) {
572 }
573
574 if (priv->last_lsr & MCT_U232_LSR_BI) {
575 }
576 tty_kref_put(tty);
577 }
578#endif
579 wake_up_interruptible(&port->port.delta_msr_wait);
580 spin_unlock_irqrestore(&priv->lock, flags);
581exit:
582 retval = usb_submit_urb(urb, GFP_ATOMIC);
583 if (retval)
584 dev_err(&port->dev,
585 "%s - usb_submit_urb failed with result %d\n",
586 __func__, retval);
587}
588
589static void mct_u232_set_termios(struct tty_struct *tty,
590 struct usb_serial_port *port,
591 struct ktermios *old_termios)
592{
593 struct usb_serial *serial = port->serial;
594 struct mct_u232_private *priv = usb_get_serial_port_data(port);
595 struct ktermios *termios = &tty->termios;
596 unsigned int cflag = termios->c_cflag;
597 unsigned int old_cflag = old_termios->c_cflag;
598 unsigned long flags;
599 unsigned int control_state;
600 unsigned char last_lcr;
601
602
603 spin_lock_irqsave(&priv->lock, flags);
604 control_state = priv->control_state;
605 spin_unlock_irqrestore(&priv->lock, flags);
606 last_lcr = 0;
607
608
609
610
611
612
613
614
615
616 if ((old_cflag & CBAUD) == B0) {
617 dev_dbg(&port->dev, "%s: baud was B0\n", __func__);
618 control_state |= TIOCM_DTR | TIOCM_RTS;
619 mct_u232_set_modem_ctrl(port, control_state);
620 }
621
622 mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty));
623
624 if ((cflag & CBAUD) == B0) {
625 dev_dbg(&port->dev, "%s: baud is B0\n", __func__);
626
627 control_state &= ~(TIOCM_DTR | TIOCM_RTS);
628 mct_u232_set_modem_ctrl(port, control_state);
629 }
630
631
632
633
634
635
636 if (cflag & PARENB)
637 last_lcr |= (cflag & PARODD) ?
638 MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
639 else
640 last_lcr |= MCT_U232_PARITY_NONE;
641
642
643 switch (cflag & CSIZE) {
644 case CS5:
645 last_lcr |= MCT_U232_DATA_BITS_5; break;
646 case CS6:
647 last_lcr |= MCT_U232_DATA_BITS_6; break;
648 case CS7:
649 last_lcr |= MCT_U232_DATA_BITS_7; break;
650 case CS8:
651 last_lcr |= MCT_U232_DATA_BITS_8; break;
652 default:
653 dev_err(&port->dev,
654 "CSIZE was not CS5-CS8, using default of 8\n");
655 last_lcr |= MCT_U232_DATA_BITS_8;
656 break;
657 }
658
659 termios->c_cflag &= ~CMSPAR;
660
661
662 last_lcr |= (cflag & CSTOPB) ?
663 MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
664
665 mct_u232_set_line_ctrl(port, last_lcr);
666
667
668 spin_lock_irqsave(&priv->lock, flags);
669 priv->control_state = control_state;
670 priv->last_lcr = last_lcr;
671 spin_unlock_irqrestore(&priv->lock, flags);
672}
673
674static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
675{
676 struct usb_serial_port *port = tty->driver_data;
677 struct mct_u232_private *priv = usb_get_serial_port_data(port);
678 unsigned char lcr;
679 unsigned long flags;
680
681 spin_lock_irqsave(&priv->lock, flags);
682 lcr = priv->last_lcr;
683
684 if (break_state)
685 lcr |= MCT_U232_SET_BREAK;
686 spin_unlock_irqrestore(&priv->lock, flags);
687
688 mct_u232_set_line_ctrl(port, lcr);
689}
690
691
692static int mct_u232_tiocmget(struct tty_struct *tty)
693{
694 struct usb_serial_port *port = tty->driver_data;
695 struct mct_u232_private *priv = usb_get_serial_port_data(port);
696 unsigned int control_state;
697 unsigned long flags;
698
699 spin_lock_irqsave(&priv->lock, flags);
700 control_state = priv->control_state;
701 spin_unlock_irqrestore(&priv->lock, flags);
702
703 return control_state;
704}
705
706static int mct_u232_tiocmset(struct tty_struct *tty,
707 unsigned int set, unsigned int clear)
708{
709 struct usb_serial_port *port = tty->driver_data;
710 struct mct_u232_private *priv = usb_get_serial_port_data(port);
711 unsigned int control_state;
712 unsigned long flags;
713
714 spin_lock_irqsave(&priv->lock, flags);
715 control_state = priv->control_state;
716
717 if (set & TIOCM_RTS)
718 control_state |= TIOCM_RTS;
719 if (set & TIOCM_DTR)
720 control_state |= TIOCM_DTR;
721 if (clear & TIOCM_RTS)
722 control_state &= ~TIOCM_RTS;
723 if (clear & TIOCM_DTR)
724 control_state &= ~TIOCM_DTR;
725
726 priv->control_state = control_state;
727 spin_unlock_irqrestore(&priv->lock, flags);
728 return mct_u232_set_modem_ctrl(port, control_state);
729}
730
731static void mct_u232_throttle(struct tty_struct *tty)
732{
733 struct usb_serial_port *port = tty->driver_data;
734 struct mct_u232_private *priv = usb_get_serial_port_data(port);
735 unsigned int control_state;
736
737 spin_lock_irq(&priv->lock);
738 priv->rx_flags |= THROTTLED;
739 if (C_CRTSCTS(tty)) {
740 priv->control_state &= ~TIOCM_RTS;
741 control_state = priv->control_state;
742 spin_unlock_irq(&priv->lock);
743 mct_u232_set_modem_ctrl(port, control_state);
744 } else {
745 spin_unlock_irq(&priv->lock);
746 }
747}
748
749static void mct_u232_unthrottle(struct tty_struct *tty)
750{
751 struct usb_serial_port *port = tty->driver_data;
752 struct mct_u232_private *priv = usb_get_serial_port_data(port);
753 unsigned int control_state;
754
755 spin_lock_irq(&priv->lock);
756 if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
757 priv->rx_flags &= ~THROTTLED;
758 priv->control_state |= TIOCM_RTS;
759 control_state = priv->control_state;
760 spin_unlock_irq(&priv->lock);
761 mct_u232_set_modem_ctrl(port, control_state);
762 } else {
763 spin_unlock_irq(&priv->lock);
764 }
765}
766
767module_usb_serial_driver(serial_drivers, id_table);
768
769MODULE_AUTHOR(DRIVER_AUTHOR);
770MODULE_DESCRIPTION(DRIVER_DESC);
771MODULE_LICENSE("GPL");
772