1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67#include <linux/config.h>
68#include <linux/kernel.h>
69#include <linux/errno.h>
70#include <linux/init.h>
71#include <linux/slab.h>
72#include <linux/tty.h>
73#include <linux/tty_driver.h>
74#include <linux/tty_flip.h>
75#include <linux/module.h>
76#include <linux/spinlock.h>
77#include <asm/uaccess.h>
78#include <linux/usb.h>
79
80#ifdef CONFIG_USB_SERIAL_DEBUG
81 static int debug = 1;
82#else
83 static int debug;
84#endif
85
86#include "usb-serial.h"
87#include "mct_u232.h"
88
89
90
91
92#define DRIVER_VERSION "z2.0"
93#define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
94#define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
95
96
97
98
99static int mct_u232_startup (struct usb_serial *serial);
100static void mct_u232_shutdown (struct usb_serial *serial);
101static int mct_u232_open (struct usb_serial_port *port,
102 struct file *filp);
103static void mct_u232_close (struct usb_serial_port *port,
104 struct file *filp);
105static void mct_u232_read_int_callback (struct urb *urb);
106static void mct_u232_set_termios (struct usb_serial_port *port,
107 struct termios * old);
108static int mct_u232_ioctl (struct usb_serial_port *port,
109 struct file * file,
110 unsigned int cmd,
111 unsigned long arg);
112static void mct_u232_break_ctl (struct usb_serial_port *port,
113 int break_state );
114
115
116
117
118static struct usb_device_id id_table_combined [] = {
119 { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
120 { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
121 { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
122 { USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },
123 { }
124};
125
126MODULE_DEVICE_TABLE (usb, id_table_combined);
127
128
129static struct usb_serial_device_type mct_u232_device = {
130 .owner = THIS_MODULE,
131 .name = "MCT U232",
132 .id_table = id_table_combined,
133 .num_interrupt_in = 2,
134 .num_bulk_in = 0,
135 .num_bulk_out = 1,
136 .num_ports = 1,
137 .open = mct_u232_open,
138 .close = mct_u232_close,
139 .read_int_callback = mct_u232_read_int_callback,
140 .ioctl = mct_u232_ioctl,
141 .set_termios = mct_u232_set_termios,
142 .break_ctl = mct_u232_break_ctl,
143 .startup = mct_u232_startup,
144 .shutdown = mct_u232_shutdown,
145};
146
147struct mct_u232_interval_kludge {
148 int ecnt;
149 int ibase;
150};
151
152struct mct_u232_private {
153 spinlock_t lock;
154 struct mct_u232_interval_kludge ik[2];
155 unsigned int control_state;
156 unsigned char last_lcr;
157 unsigned char last_lsr;
158 unsigned char last_msr;
159};
160
161
162
163
164
165#define WDR_TIMEOUT (HZ * 5 )
166
167
168
169
170
171
172static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) {
173 if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID
174 || serial->dev->descriptor.idProduct == MCT_U232_BELKIN_F5U109_PID) {
175 switch (value) {
176 case B300: return 0x01;
177 case B600: return 0x02;
178 case B1200: return 0x03;
179 case B2400: return 0x04;
180 case B4800: return 0x06;
181 case B9600: return 0x08;
182 case B19200: return 0x09;
183 case B38400: return 0x0a;
184 case B57600: return 0x0b;
185 case B115200: return 0x0c;
186 default:
187 err("MCT USB-RS232: unsupported baudrate request 0x%x,"
188 " using default of B9600", value);
189 return 0x08;
190 }
191 } else {
192 switch (value) {
193 case B300: value = 300; break;
194 case B600: value = 600; break;
195 case B1200: value = 1200; break;
196 case B2400: value = 2400; break;
197 case B4800: value = 4800; break;
198 case B9600: value = 9600; break;
199 case B19200: value = 19200; break;
200 case B38400: value = 38400; break;
201 case B57600: value = 57600; break;
202 case B115200: value = 115200; break;
203 default:
204 err("MCT USB-RS232: unsupported baudrate request 0x%x,"
205 " using default of B9600", value);
206 value = 9600;
207 }
208 return 115200/value;
209 }
210}
211
212static int mct_u232_set_baud_rate(struct usb_serial *serial, int value)
213{
214 unsigned int divisor;
215 int rc;
216 unsigned char zero_byte = 0;
217
218 divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value));
219
220 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
221 MCT_U232_SET_BAUD_RATE_REQUEST,
222 MCT_U232_SET_REQUEST_TYPE,
223 0, 0, &divisor, MCT_U232_SET_BAUD_RATE_SIZE,
224 WDR_TIMEOUT);
225 if (rc < 0)
226 err("Set BAUD RATE %d failed (error = %d)", value, rc);
227 dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor);
228
229
230
231
232
233
234
235
236
237
238
239 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
240 MCT_U232_SET_UNKNOWN1_REQUEST,
241 MCT_U232_SET_REQUEST_TYPE,
242 0, 0, &zero_byte, MCT_U232_SET_UNKNOWN1_SIZE,
243 WDR_TIMEOUT);
244 if (rc < 0)
245 err("Sending USB device request code %d failed (error = %d)",
246 MCT_U232_SET_UNKNOWN1_REQUEST, rc);
247
248 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
249 MCT_U232_SET_UNKNOWN2_REQUEST,
250 MCT_U232_SET_REQUEST_TYPE,
251 0, 0, &zero_byte, MCT_U232_SET_UNKNOWN2_SIZE,
252 WDR_TIMEOUT);
253 if (rc < 0)
254 err("Sending USB device request code %d failed (error = %d)",
255 MCT_U232_SET_UNKNOWN2_REQUEST, rc);
256
257 return rc;
258}
259
260static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr)
261{
262 int rc;
263 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
264 MCT_U232_SET_LINE_CTRL_REQUEST,
265 MCT_U232_SET_REQUEST_TYPE,
266 0, 0, &lcr, MCT_U232_SET_LINE_CTRL_SIZE,
267 WDR_TIMEOUT);
268 if (rc < 0)
269 err("Set LINE CTRL 0x%x failed (error = %d)", lcr, rc);
270 dbg("set_line_ctrl: 0x%x", lcr);
271 return rc;
272}
273
274static int mct_u232_set_modem_ctrl(struct usb_serial *serial,
275 unsigned int control_state)
276{
277 int rc;
278 unsigned char mcr = MCT_U232_MCR_NONE;
279
280 if (control_state & TIOCM_DTR)
281 mcr |= MCT_U232_MCR_DTR;
282 if (control_state & TIOCM_RTS)
283 mcr |= MCT_U232_MCR_RTS;
284
285 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
286 MCT_U232_SET_MODEM_CTRL_REQUEST,
287 MCT_U232_SET_REQUEST_TYPE,
288 0, 0, &mcr, MCT_U232_SET_MODEM_CTRL_SIZE,
289 WDR_TIMEOUT);
290 if (rc < 0)
291 err("Set MODEM CTRL 0x%x failed (error = %d)", mcr, rc);
292 dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr);
293
294 return rc;
295}
296
297static int mct_u232_get_modem_stat(struct usb_serial *serial, unsigned char *msr)
298{
299 int rc;
300 rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
301 MCT_U232_GET_MODEM_STAT_REQUEST,
302 MCT_U232_GET_REQUEST_TYPE,
303 0, 0, msr, MCT_U232_GET_MODEM_STAT_SIZE,
304 WDR_TIMEOUT);
305 if (rc < 0) {
306 err("Get MODEM STATus failed (error = %d)", rc);
307 *msr = 0;
308 }
309 dbg("get_modem_stat: 0x%x", *msr);
310 return rc;
311}
312
313static void mct_u232_msr_to_state(unsigned int *control_state, unsigned char msr)
314{
315
316 if (msr & MCT_U232_MSR_DSR)
317 *control_state |= TIOCM_DSR;
318 else
319 *control_state &= ~TIOCM_DSR;
320 if (msr & MCT_U232_MSR_CTS)
321 *control_state |= TIOCM_CTS;
322 else
323 *control_state &= ~TIOCM_CTS;
324 if (msr & MCT_U232_MSR_RI)
325 *control_state |= TIOCM_RI;
326 else
327 *control_state &= ~TIOCM_RI;
328 if (msr & MCT_U232_MSR_CD)
329 *control_state |= TIOCM_CD;
330 else
331 *control_state &= ~TIOCM_CD;
332 dbg("msr_to_state: msr=0x%x ==> state=0x%x", msr, *control_state);
333}
334
335
336
337
338
339static int mct_u232_startup (struct usb_serial *serial)
340{
341 struct mct_u232_private *priv;
342 struct usb_serial_port *port, *rport;
343
344 priv = kmalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
345 if (!priv)
346 return -ENOMEM;
347 memset(priv, 0, sizeof(struct mct_u232_private));
348 spin_lock_init(&priv->lock);
349 serial->port->private = priv;
350
351 init_waitqueue_head(&serial->port->write_wait);
352
353
354 port = &serial->port[0];
355 rport = &serial->port[1];
356 if (port->read_urb) {
357
358 usb_free_urb(port->read_urb);
359 }
360 port->read_urb = rport->interrupt_in_urb;
361 rport->interrupt_in_urb = NULL;
362 port->read_urb->context = port;
363
364 priv->ik[0].ibase = port->read_urb->interval;
365 priv->ik[1].ibase = port->interrupt_in_urb->interval;
366
367 return (0);
368}
369
370
371static void mct_u232_shutdown (struct usb_serial *serial)
372{
373 struct mct_u232_private *priv;
374 int i;
375
376 dbg("%s", __FUNCTION__);
377
378 for (i=0; i < serial->num_ports; ++i) {
379
380 priv = serial->port[i].private;
381 if (priv) {
382 serial->port[i].private = NULL;
383 kfree(priv);
384 }
385 }
386}
387
388static int mct_u232_open (struct usb_serial_port *port, struct file *filp)
389{
390 struct usb_serial *serial = port->serial;
391 struct mct_u232_private *priv = (struct mct_u232_private *)port->private;
392 int retval = 0;
393 unsigned int control_state;
394 unsigned long flags;
395 unsigned char last_lcr;
396 unsigned char last_msr;
397
398 dbg("%s port %d", __FUNCTION__, port->number);
399
400
401
402
403
404
405 if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID)
406 port->bulk_out_size = 16;
407
408
409
410
411
412
413 spin_lock_irqsave(&priv->lock, flags);
414 if (port->tty->termios->c_cflag & CBAUD)
415 priv->control_state = TIOCM_DTR | TIOCM_RTS;
416 else
417 priv->control_state = 0;
418
419 priv->last_lcr = (MCT_U232_DATA_BITS_8 |
420 MCT_U232_PARITY_NONE |
421 MCT_U232_STOP_BITS_1);
422 control_state = priv->control_state;
423 last_lcr = priv->last_lcr;
424 spin_unlock_irqrestore(&priv->lock, flags);
425 mct_u232_set_modem_ctrl(serial, control_state);
426 mct_u232_set_line_ctrl(serial, last_lcr);
427
428
429 mct_u232_get_modem_stat(serial, &last_msr);
430 spin_lock_irqsave(&priv->lock, flags);
431 priv->last_msr = last_msr;
432 mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
433 spin_unlock_irqrestore(&priv->lock, flags);
434
435 port->read_urb->dev = port->serial->dev;
436 port->read_urb->interval = priv->ik[0].ibase;
437 retval = usb_submit_urb(port->read_urb);
438 if (retval) {
439 err("usb_submit_urb(read bulk) failed pipe 0x%x err %d",
440 port->read_urb->pipe, retval);
441 goto exit;
442 }
443
444 port->interrupt_in_urb->dev = port->serial->dev;
445 port->interrupt_in_urb->interval = priv->ik[1].ibase;
446 retval = usb_submit_urb(port->interrupt_in_urb);
447 if (retval)
448 err(" usb_submit_urb(read int) failed pipe 0x%x err %d",
449 port->interrupt_in_urb->pipe, retval);
450
451exit:
452 return 0;
453}
454
455
456static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
457{
458 dbg("%s port %d", __FUNCTION__, port->number);
459
460 if (port->serial->dev) {
461
462 usb_unlink_urb (port->write_urb);
463 usb_unlink_urb (port->read_urb);
464 usb_unlink_urb (port->interrupt_in_urb);
465 }
466}
467
468static void mct_u232_error_step (struct urb *urb,
469 struct mct_u232_private *priv, int n)
470{
471 struct mct_u232_interval_kludge *ikp = &priv->ik[n];
472
473 if (ikp->ecnt >= 2) {
474 if (urb->interval)
475 err("%s - too many errors: "
476 "status %d pipe 0x%x interval %d",
477 __FUNCTION__,
478 urb->status, urb->pipe, urb->interval);
479 urb->interval = 0;
480 } else {
481 ++ikp->ecnt;
482 }
483}
484
485static void mct_u232_read_int_callback (struct urb *urb)
486{
487 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
488 struct mct_u232_private *priv = (struct mct_u232_private *)port->private;
489 struct usb_serial *serial = port->serial;
490 struct tty_struct *tty;
491 unsigned char *data = urb->transfer_buffer;
492 unsigned long flags;
493
494
495 if (urb->status) {
496 dbg("%s - nonzero status %d, pipe 0x%x flags 0x%x interval %d",
497 __FUNCTION__,
498 urb->status, urb->pipe, urb->transfer_flags, urb->interval);
499
500
501
502
503
504
505
506 if (urb == port->read_urb)
507 mct_u232_error_step(urb, priv, 0);
508 if (urb == port->interrupt_in_urb)
509 mct_u232_error_step(urb, priv, 1);
510 return;
511 }
512 if (!serial) {
513 dbg("%s - bad serial pointer, exiting", __FUNCTION__);
514 return;
515 }
516
517 dbg("%s - port %d", __FUNCTION__, port->number);
518 usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
519
520 if (urb == port->read_urb)
521 priv->ik[0].ecnt = 0;
522 if (urb == port->interrupt_in_urb)
523 priv->ik[1].ecnt = 0;
524
525
526
527
528 if (urb->transfer_buffer_length > 2) {
529 int i;
530 tty = port->tty;
531 if (urb->actual_length) {
532 for (i = 0; i < urb->actual_length ; ++i) {
533 tty_insert_flip_char(tty, data[i], 0);
534 }
535 tty_flip_buffer_push(tty);
536 }
537
538 return;
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(&priv->control_state, priv->last_msr);
550
551#if 0
552
553
554 priv->last_lsr = data[MCT_U232_LSR_INDEX];
555
556
557
558
559
560 if (priv->last_lsr & MCT_U232_LSR_ERR) {
561 tty = port->tty;
562
563 if (priv->last_lsr & MCT_U232_LSR_OE) {
564 }
565
566 if (priv->last_lsr & MCT_U232_LSR_PE) {
567 }
568
569 if (priv->last_lsr & MCT_U232_LSR_FE) {
570 }
571
572 if (priv->last_lsr & MCT_U232_LSR_BI) {
573 }
574 }
575#endif
576 spin_unlock_irqrestore(&priv->lock, flags);
577
578
579}
580
581static void mct_u232_set_termios (struct usb_serial_port *port,
582 struct termios *old_termios)
583{
584 struct usb_serial *serial = port->serial;
585 struct mct_u232_private *priv = (struct mct_u232_private *)port->private;
586 unsigned int iflag = port->tty->termios->c_iflag;
587 unsigned int cflag = port->tty->termios->c_cflag;
588 unsigned int old_cflag = old_termios->c_cflag;
589 unsigned long flags;
590 unsigned int control_state, new_state;
591 unsigned char last_lcr;
592
593
594 spin_lock_irqsave(&priv->lock, flags);
595 control_state = priv->control_state;
596 spin_unlock_irqrestore(&priv->lock, flags);
597 last_lcr = 0;
598
599
600
601
602
603
604
605
606
607 if ((old_cflag & CBAUD) == B0) {
608 dbg("%s: baud was B0", __FUNCTION__);
609 control_state |= TIOCM_DTR;
610
611 if (!(old_cflag & CRTSCTS)) {
612 control_state |= TIOCM_RTS;
613 }
614 mct_u232_set_modem_ctrl(serial, control_state);
615 }
616
617 mct_u232_set_baud_rate(serial, cflag & CBAUD);
618
619 if ((cflag & CBAUD) == B0 ) {
620 dbg("%s: baud is B0", __FUNCTION__);
621
622 control_state &= ~(TIOCM_DTR | TIOCM_RTS);
623 mct_u232_set_modem_ctrl(serial, control_state);
624 }
625
626
627
628
629
630
631 if (cflag & PARENB)
632 last_lcr |= (cflag & PARODD) ?
633 MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
634 else
635 last_lcr |= MCT_U232_PARITY_NONE;
636
637
638 switch (cflag & CSIZE) {
639 case CS5:
640 last_lcr |= MCT_U232_DATA_BITS_5; break;
641 case CS6:
642 last_lcr |= MCT_U232_DATA_BITS_6; break;
643 case CS7:
644 last_lcr |= MCT_U232_DATA_BITS_7; break;
645 case CS8:
646 last_lcr |= MCT_U232_DATA_BITS_8; break;
647 default:
648 err("CSIZE was not CS5-CS8, using default of 8");
649 last_lcr |= MCT_U232_DATA_BITS_8;
650 break;
651 }
652
653
654 last_lcr |= (cflag & CSTOPB) ?
655 MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
656
657 mct_u232_set_line_ctrl(serial, last_lcr);
658
659
660
661
662
663
664 new_state = control_state;
665 if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS))
666 new_state |= TIOCM_DTR | TIOCM_RTS;
667 else
668 new_state &= ~(TIOCM_DTR | TIOCM_RTS);
669 if (new_state != control_state) {
670 mct_u232_set_modem_ctrl(serial, new_state);
671 control_state = new_state;
672 }
673
674
675 spin_lock_irqsave(&priv->lock, flags);
676 priv->control_state = control_state;
677 priv->last_lcr = last_lcr;
678 spin_unlock_irqrestore(&priv->lock, flags);
679}
680
681static void mct_u232_break_ctl( struct usb_serial_port *port, int break_state )
682{
683 struct usb_serial *serial = port->serial;
684 struct mct_u232_private *priv = (struct mct_u232_private *)port->private;
685 unsigned char lcr;
686 unsigned long flags;
687
688 dbg("%sstate=%d", __FUNCTION__, break_state);
689
690 spin_lock_irqsave(&priv->lock, flags);
691 lcr = priv->last_lcr;
692 spin_unlock_irqrestore(&priv->lock, flags);
693
694 if (break_state)
695 lcr |= MCT_U232_SET_BREAK;
696
697 mct_u232_set_line_ctrl(serial, lcr);
698}
699
700
701static int mct_u232_tiocmget (struct usb_serial_port *port, struct file *file)
702{
703 struct mct_u232_private *priv = (struct mct_u232_private *)port->private;
704 unsigned int control_state;
705 unsigned long flags;
706
707 dbg("%s", __FUNCTION__);
708
709 spin_lock_irqsave(&priv->lock, flags);
710 control_state = priv->control_state;
711 spin_unlock_irqrestore(&priv->lock, flags);
712
713 return control_state;
714}
715
716static int mct_u232_ioctl (struct usb_serial_port *port, struct file * file,
717 unsigned int cmd, unsigned long arg)
718{
719 struct usb_serial *serial = port->serial;
720 struct mct_u232_private *priv = (struct mct_u232_private *)port->private;
721 int mask;
722 unsigned long flags;
723
724 dbg("%scmd=0x%x", __FUNCTION__, cmd);
725
726
727 switch (cmd) {
728 case TIOCMGET:
729 mask = mct_u232_tiocmget(port, file);
730 return put_user(mask, (unsigned long *) arg);
731
732 case TIOCMSET:
733 case TIOCMBIS:
734 case TIOCMBIC:
735 if (get_user(mask, (unsigned long *) arg))
736 return -EFAULT;
737
738 spin_lock_irqsave(&priv->lock, flags);
739 if ((cmd == TIOCMSET) || (mask & TIOCM_RTS)) {
740
741 if( ((cmd == TIOCMSET) && (mask & TIOCM_RTS)) ||
742 (cmd == TIOCMBIS) )
743 priv->control_state |= TIOCM_RTS;
744 else
745 priv->control_state &= ~TIOCM_RTS;
746 }
747
748 if ((cmd == TIOCMSET) || (mask & TIOCM_DTR)) {
749
750 if( ((cmd == TIOCMSET) && (mask & TIOCM_DTR)) ||
751 (cmd == TIOCMBIS) )
752 priv->control_state |= TIOCM_DTR;
753 else
754 priv->control_state &= ~TIOCM_DTR;
755 }
756 spin_unlock_irqrestore(&priv->lock, flags);
757 mct_u232_set_modem_ctrl(serial, priv->control_state);
758 break;
759
760 case TIOCMIWAIT:
761
762
763 return( 0 );
764
765 case TIOCGICOUNT:
766
767
768 return 0;
769
770 default:
771 dbg("%s: arg not supported - 0x%04x", __FUNCTION__,cmd);
772 return(-ENOIOCTLCMD);
773 break;
774 }
775 return 0;
776}
777
778
779static int __init mct_u232_init (void)
780{
781 usb_serial_register (&mct_u232_device);
782 info(DRIVER_DESC " " DRIVER_VERSION);
783 return 0;
784}
785
786
787static void __exit mct_u232_exit (void)
788{
789 usb_serial_deregister (&mct_u232_device);
790}
791
792
793module_init (mct_u232_init);
794module_exit(mct_u232_exit);
795
796MODULE_AUTHOR( DRIVER_AUTHOR );
797MODULE_DESCRIPTION( DRIVER_DESC );
798MODULE_LICENSE("GPL");
799
800MODULE_PARM(debug, "i");
801MODULE_PARM_DESC(debug, "Debug enabled or not");
802