mct_u232.c (7af75af2424c3a866041e7981d91f01f93235533) mct_u232.c (60b33c133ca0b7c0b6072c87234b63fee6e80558)
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

--- 64 unchanged lines hidden (view full) ---

73#include <linux/tty_driver.h>
74#include <linux/tty_flip.h>
75#include <linux/module.h>
76#include <linux/spinlock.h>
77#include <linux/uaccess.h>
78#include <asm/unaligned.h>
79#include <linux/usb.h>
80#include <linux/usb/serial.h>
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

--- 64 unchanged lines hidden (view full) ---

73#include <linux/tty_driver.h>
74#include <linux/tty_flip.h>
75#include <linux/module.h>
76#include <linux/spinlock.h>
77#include <linux/uaccess.h>
78#include <asm/unaligned.h>
79#include <linux/usb.h>
80#include <linux/usb/serial.h>
81#include <linux/serial.h>
82#include <linux/ioctl.h>
83#include "mct_u232.h"
84
85/*
86 * Version Information
87 */
88#define DRIVER_VERSION "z2.1" /* Linux in-kernel version */
89#define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
90#define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"

--- 7 unchanged lines hidden (view full) ---

98static void mct_u232_release(struct usb_serial *serial);
99static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);
100static void mct_u232_close(struct usb_serial_port *port);
101static void mct_u232_dtr_rts(struct usb_serial_port *port, int on);
102static void mct_u232_read_int_callback(struct urb *urb);
103static void mct_u232_set_termios(struct tty_struct *tty,
104 struct usb_serial_port *port, struct ktermios *old);
105static void mct_u232_break_ctl(struct tty_struct *tty, int break_state);
81#include "mct_u232.h"
82
83/*
84 * Version Information
85 */
86#define DRIVER_VERSION "z2.1" /* Linux in-kernel version */
87#define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
88#define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"

--- 7 unchanged lines hidden (view full) ---

96static void mct_u232_release(struct usb_serial *serial);
97static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);
98static void mct_u232_close(struct usb_serial_port *port);
99static void mct_u232_dtr_rts(struct usb_serial_port *port, int on);
100static void mct_u232_read_int_callback(struct urb *urb);
101static void mct_u232_set_termios(struct tty_struct *tty,
102 struct usb_serial_port *port, struct ktermios *old);
103static void mct_u232_break_ctl(struct tty_struct *tty, int break_state);
106static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file);
104static int mct_u232_tiocmget(struct tty_struct *tty);
107static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file,
108 unsigned int set, unsigned int clear);
105static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file,
106 unsigned int set, unsigned int clear);
109static int mct_u232_ioctl(struct tty_struct *tty, struct file *file,
110 unsigned int cmd, unsigned long arg);
111static int mct_u232_get_icount(struct tty_struct *tty,
112 struct serial_icounter_struct *icount);
113static void mct_u232_throttle(struct tty_struct *tty);
114static void mct_u232_unthrottle(struct tty_struct *tty);
115
116
117/*
118 * All of the device info needed for the MCT USB-RS232 converter.
119 */
120static const struct usb_device_id id_table_combined[] = {

--- 30 unchanged lines hidden (view full) ---

151 .unthrottle = mct_u232_unthrottle,
152 .read_int_callback = mct_u232_read_int_callback,
153 .set_termios = mct_u232_set_termios,
154 .break_ctl = mct_u232_break_ctl,
155 .tiocmget = mct_u232_tiocmget,
156 .tiocmset = mct_u232_tiocmset,
157 .attach = mct_u232_startup,
158 .release = mct_u232_release,
107static void mct_u232_throttle(struct tty_struct *tty);
108static void mct_u232_unthrottle(struct tty_struct *tty);
109
110
111/*
112 * All of the device info needed for the MCT USB-RS232 converter.
113 */
114static const struct usb_device_id id_table_combined[] = {

--- 30 unchanged lines hidden (view full) ---

145 .unthrottle = mct_u232_unthrottle,
146 .read_int_callback = mct_u232_read_int_callback,
147 .set_termios = mct_u232_set_termios,
148 .break_ctl = mct_u232_break_ctl,
149 .tiocmget = mct_u232_tiocmget,
150 .tiocmset = mct_u232_tiocmset,
151 .attach = mct_u232_startup,
152 .release = mct_u232_release,
159 .ioctl = mct_u232_ioctl,
160 .get_icount = mct_u232_get_icount,
161};
162
153};
154
155
163struct mct_u232_private {
164 spinlock_t lock;
165 unsigned int control_state; /* Modem Line Setting (TIOCM) */
166 unsigned char last_lcr; /* Line Control Register */
167 unsigned char last_lsr; /* Line Status Register */
168 unsigned char last_msr; /* Modem Status Register */
169 unsigned int rx_flags; /* Throttling flags */
156struct mct_u232_private {
157 spinlock_t lock;
158 unsigned int control_state; /* Modem Line Setting (TIOCM) */
159 unsigned char last_lcr; /* Line Control Register */
160 unsigned char last_lsr; /* Line Status Register */
161 unsigned char last_msr; /* Modem Status Register */
162 unsigned int rx_flags; /* Throttling flags */
170 struct async_icount icount;
171 wait_queue_head_t msr_wait; /* for handling sleeping while waiting
172 for msr change to happen */
173};
174
175#define THROTTLED 0x01
176
177/*
178 * Handle vendor specific USB requests
179 */
180

--- 210 unchanged lines hidden (view full) ---

391 } else {
392 *msr = buf[0];
393 }
394 dbg("get_modem_stat: 0x%x", *msr);
395 kfree(buf);
396 return rc;
397} /* mct_u232_get_modem_stat */
398
163};
164
165#define THROTTLED 0x01
166
167/*
168 * Handle vendor specific USB requests
169 */
170

--- 210 unchanged lines hidden (view full) ---

381 } else {
382 *msr = buf[0];
383 }
384 dbg("get_modem_stat: 0x%x", *msr);
385 kfree(buf);
386 return rc;
387} /* mct_u232_get_modem_stat */
388
399static void mct_u232_msr_to_icount(struct async_icount *icount,
400 unsigned char msr)
401{
402 /* Translate Control Line states */
403 if (msr & MCT_U232_MSR_DDSR)
404 icount->dsr++;
405 if (msr & MCT_U232_MSR_DCTS)
406 icount->cts++;
407 if (msr & MCT_U232_MSR_DRI)
408 icount->rng++;
409 if (msr & MCT_U232_MSR_DCD)
410 icount->dcd++;
411} /* mct_u232_msr_to_icount */
412
413static void mct_u232_msr_to_state(unsigned int *control_state,
414 unsigned char msr)
415{
416 /* Translate Control Line states */
417 if (msr & MCT_U232_MSR_DSR)
418 *control_state |= TIOCM_DSR;
419 else
420 *control_state &= ~TIOCM_DSR;

--- 20 unchanged lines hidden (view full) ---

441{
442 struct mct_u232_private *priv;
443 struct usb_serial_port *port, *rport;
444
445 priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
446 if (!priv)
447 return -ENOMEM;
448 spin_lock_init(&priv->lock);
389static void mct_u232_msr_to_state(unsigned int *control_state,
390 unsigned char msr)
391{
392 /* Translate Control Line states */
393 if (msr & MCT_U232_MSR_DSR)
394 *control_state |= TIOCM_DSR;
395 else
396 *control_state &= ~TIOCM_DSR;

--- 20 unchanged lines hidden (view full) ---

417{
418 struct mct_u232_private *priv;
419 struct usb_serial_port *port, *rport;
420
421 priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
422 if (!priv)
423 return -ENOMEM;
424 spin_lock_init(&priv->lock);
449 init_waitqueue_head(&priv->msr_wait);
450 usb_set_serial_port_data(serial->port[0], priv);
451
452 init_waitqueue_head(&serial->port[0]->write_wait);
453
454 /* Puh, that's dirty */
455 port = serial->port[0];
456 rport = serial->port[1];
457 /* No unlinking, it wasn't submitted yet. */

--- 183 unchanged lines hidden (view full) ---

641 * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
642 */
643 spin_lock_irqsave(&priv->lock, flags);
644 priv->last_msr = data[MCT_U232_MSR_INDEX];
645
646 /* Record Control Line states */
647 mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
648
425 usb_set_serial_port_data(serial->port[0], priv);
426
427 init_waitqueue_head(&serial->port[0]->write_wait);
428
429 /* Puh, that's dirty */
430 port = serial->port[0];
431 rport = serial->port[1];
432 /* No unlinking, it wasn't submitted yet. */

--- 183 unchanged lines hidden (view full) ---

616 * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
617 */
618 spin_lock_irqsave(&priv->lock, flags);
619 priv->last_msr = data[MCT_U232_MSR_INDEX];
620
621 /* Record Control Line states */
622 mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
623
649 mct_u232_msr_to_icount(&priv->icount, priv->last_msr);
650
651#if 0
652 /* Not yet handled. See belkin_sa.c for further information */
653 /* Now to report any errors */
654 priv->last_lsr = data[MCT_U232_LSR_INDEX];
655 /*
656 * fill in the flip buffer here, but I do not know the relation
657 * to the current/next receive buffer or characters. I need
658 * to look in to this before committing any code.

--- 10 unchanged lines hidden (view full) ---

669 if (priv->last_lsr & MCT_U232_LSR_FE) {
670 }
671 /* Break Indicator */
672 if (priv->last_lsr & MCT_U232_LSR_BI) {
673 }
674 tty_kref_put(tty);
675 }
676#endif
624#if 0
625 /* Not yet handled. See belkin_sa.c for further information */
626 /* Now to report any errors */
627 priv->last_lsr = data[MCT_U232_LSR_INDEX];
628 /*
629 * fill in the flip buffer here, but I do not know the relation
630 * to the current/next receive buffer or characters. I need
631 * to look in to this before committing any code.

--- 10 unchanged lines hidden (view full) ---

642 if (priv->last_lsr & MCT_U232_LSR_FE) {
643 }
644 /* Break Indicator */
645 if (priv->last_lsr & MCT_U232_LSR_BI) {
646 }
647 tty_kref_put(tty);
648 }
649#endif
677 wake_up_interruptible(&priv->msr_wait);
678 spin_unlock_irqrestore(&priv->lock, flags);
679exit:
680 retval = usb_submit_urb(urb, GFP_ATOMIC);
681 if (retval)
682 dev_err(&port->dev,
683 "%s - usb_submit_urb failed with result %d\n",
684 __func__, retval);
685} /* mct_u232_read_int_callback */

--- 99 unchanged lines hidden (view full) ---

785 if (break_state)
786 lcr |= MCT_U232_SET_BREAK;
787 spin_unlock_irqrestore(&priv->lock, flags);
788
789 mct_u232_set_line_ctrl(serial, lcr);
790} /* mct_u232_break_ctl */
791
792
650 spin_unlock_irqrestore(&priv->lock, flags);
651exit:
652 retval = usb_submit_urb(urb, GFP_ATOMIC);
653 if (retval)
654 dev_err(&port->dev,
655 "%s - usb_submit_urb failed with result %d\n",
656 __func__, retval);
657} /* mct_u232_read_int_callback */

--- 99 unchanged lines hidden (view full) ---

757 if (break_state)
758 lcr |= MCT_U232_SET_BREAK;
759 spin_unlock_irqrestore(&priv->lock, flags);
760
761 mct_u232_set_line_ctrl(serial, lcr);
762} /* mct_u232_break_ctl */
763
764
793static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file)
765static int mct_u232_tiocmget(struct tty_struct *tty)
794{
795 struct usb_serial_port *port = tty->driver_data;
796 struct mct_u232_private *priv = usb_get_serial_port_data(port);
797 unsigned int control_state;
798 unsigned long flags;
799
800 dbg("%s", __func__);
801

--- 47 unchanged lines hidden (view full) ---

849 control_state = priv->control_state;
850 spin_unlock_irq(&priv->lock);
851 (void) mct_u232_set_modem_ctrl(port->serial, control_state);
852 } else {
853 spin_unlock_irq(&priv->lock);
854 }
855}
856
766{
767 struct usb_serial_port *port = tty->driver_data;
768 struct mct_u232_private *priv = usb_get_serial_port_data(port);
769 unsigned int control_state;
770 unsigned long flags;
771
772 dbg("%s", __func__);
773

--- 47 unchanged lines hidden (view full) ---

821 control_state = priv->control_state;
822 spin_unlock_irq(&priv->lock);
823 (void) mct_u232_set_modem_ctrl(port->serial, control_state);
824 } else {
825 spin_unlock_irq(&priv->lock);
826 }
827}
828
829
857static void mct_u232_unthrottle(struct tty_struct *tty)
858{
859 struct usb_serial_port *port = tty->driver_data;
860 struct mct_u232_private *priv = usb_get_serial_port_data(port);
861 unsigned int control_state;
862
863 dbg("%s - port %d", __func__, port->number);
864

--- 4 unchanged lines hidden (view full) ---

869 control_state = priv->control_state;
870 spin_unlock_irq(&priv->lock);
871 (void) mct_u232_set_modem_ctrl(port->serial, control_state);
872 } else {
873 spin_unlock_irq(&priv->lock);
874 }
875}
876
830static void mct_u232_unthrottle(struct tty_struct *tty)
831{
832 struct usb_serial_port *port = tty->driver_data;
833 struct mct_u232_private *priv = usb_get_serial_port_data(port);
834 unsigned int control_state;
835
836 dbg("%s - port %d", __func__, port->number);
837

--- 4 unchanged lines hidden (view full) ---

842 control_state = priv->control_state;
843 spin_unlock_irq(&priv->lock);
844 (void) mct_u232_set_modem_ctrl(port->serial, control_state);
845 } else {
846 spin_unlock_irq(&priv->lock);
847 }
848}
849
877static int mct_u232_ioctl(struct tty_struct *tty, struct file *file,
878 unsigned int cmd, unsigned long arg)
879{
880 DEFINE_WAIT(wait);
881 struct usb_serial_port *port = tty->driver_data;
882 struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port);
883 struct async_icount cnow, cprev;
884 unsigned long flags;
885
886 dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
887
888 switch (cmd) {
889
890 case TIOCMIWAIT:
891
892 dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
893
894 spin_lock_irqsave(&mct_u232_port->lock, flags);
895 cprev = mct_u232_port->icount;
896 spin_unlock_irqrestore(&mct_u232_port->lock, flags);
897 for ( ; ; ) {
898 prepare_to_wait(&mct_u232_port->msr_wait,
899 &wait, TASK_INTERRUPTIBLE);
900 schedule();
901 finish_wait(&mct_u232_port->msr_wait, &wait);
902 /* see if a signal did it */
903 if (signal_pending(current))
904 return -ERESTARTSYS;
905 spin_lock_irqsave(&mct_u232_port->lock, flags);
906 cnow = mct_u232_port->icount;
907 spin_unlock_irqrestore(&mct_u232_port->lock, flags);
908 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
909 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
910 return -EIO; /* no change => error */
911 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
912 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
913 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
914 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
915 return 0;
916 }
917 cprev = cnow;
918 }
919
920 }
921 return -ENOIOCTLCMD;
922}
923
924static int mct_u232_get_icount(struct tty_struct *tty,
925 struct serial_icounter_struct *icount)
926{
927 struct usb_serial_port *port = tty->driver_data;
928 struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port);
929 struct async_icount *ic = &mct_u232_port->icount;
930 unsigned long flags;
931
932 spin_lock_irqsave(&mct_u232_port->lock, flags);
933
934 icount->cts = ic->cts;
935 icount->dsr = ic->dsr;
936 icount->rng = ic->rng;
937 icount->dcd = ic->dcd;
938 icount->rx = ic->rx;
939 icount->tx = ic->tx;
940 icount->frame = ic->frame;
941 icount->overrun = ic->overrun;
942 icount->parity = ic->parity;
943 icount->brk = ic->brk;
944 icount->buf_overrun = ic->buf_overrun;
945
946 spin_unlock_irqrestore(&mct_u232_port->lock, flags);
947
948 dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d",
949 __func__, port->number, icount->rx, icount->tx);
950 return 0;
951}
952
953static int __init mct_u232_init(void)
954{
955 int retval;
956 retval = usb_serial_register(&mct_u232_device);
957 if (retval)
958 goto failed_usb_serial_register;
959 retval = usb_register(&mct_u232_driver);
960 if (retval)

--- 26 unchanged lines hidden ---
850static int __init mct_u232_init(void)
851{
852 int retval;
853 retval = usb_serial_register(&mct_u232_device);
854 if (retval)
855 goto failed_usb_serial_register;
856 retval = usb_register(&mct_u232_driver);
857 if (retval)

--- 26 unchanged lines hidden ---