aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2013-03-21 07:37:13 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-25 16:50:53 -0400
commit128434ab5607c6bccf385765e94382cedd3d06fa (patch)
treee1c3ad08668e66fd86a76e240edc012c88713c98
parent468c740ee5372b74e9d9bd4d7ec2d81d44e67f2d (diff)
USB: mct_u232: switch to generic TIOCMIWAIT implementation
Switch to the generic TIOCMIWAIT implementation. This also fixes the issue with processes waiting for modem-status-changes not being woken up at disconnect. Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/serial/mct_u232.c58
1 files changed, 2 insertions, 56 deletions
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 6f4303cef0d8..3353c9ed7721 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -35,7 +35,6 @@
35#include <linux/usb.h> 35#include <linux/usb.h>
36#include <linux/usb/serial.h> 36#include <linux/usb/serial.h>
37#include <linux/serial.h> 37#include <linux/serial.h>
38#include <linux/ioctl.h>
39#include "mct_u232.h" 38#include "mct_u232.h"
40 39
41#define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>" 40#define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
@@ -57,8 +56,6 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state);
57static int mct_u232_tiocmget(struct tty_struct *tty); 56static int mct_u232_tiocmget(struct tty_struct *tty);
58static int mct_u232_tiocmset(struct tty_struct *tty, 57static int mct_u232_tiocmset(struct tty_struct *tty,
59 unsigned int set, unsigned int clear); 58 unsigned int set, unsigned int clear);
60static int mct_u232_ioctl(struct tty_struct *tty,
61 unsigned int cmd, unsigned long arg);
62static void mct_u232_throttle(struct tty_struct *tty); 59static void mct_u232_throttle(struct tty_struct *tty);
63static void mct_u232_unthrottle(struct tty_struct *tty); 60static void mct_u232_unthrottle(struct tty_struct *tty);
64 61
@@ -93,10 +90,10 @@ static struct usb_serial_driver mct_u232_device = {
93 .break_ctl = mct_u232_break_ctl, 90 .break_ctl = mct_u232_break_ctl,
94 .tiocmget = mct_u232_tiocmget, 91 .tiocmget = mct_u232_tiocmget,
95 .tiocmset = mct_u232_tiocmset, 92 .tiocmset = mct_u232_tiocmset,
93 .tiocmiwait = usb_serial_generic_tiocmiwait,
96 .attach = mct_u232_startup, 94 .attach = mct_u232_startup,
97 .port_probe = mct_u232_port_probe, 95 .port_probe = mct_u232_port_probe,
98 .port_remove = mct_u232_port_remove, 96 .port_remove = mct_u232_port_remove,
99 .ioctl = mct_u232_ioctl,
100 .get_icount = usb_serial_generic_get_icount, 97 .get_icount = usb_serial_generic_get_icount,
101}; 98};
102 99
@@ -595,7 +592,7 @@ static void mct_u232_read_int_callback(struct urb *urb)
595 tty_kref_put(tty); 592 tty_kref_put(tty);
596 } 593 }
597#endif 594#endif
598 wake_up_interruptible(&port->delta_msr_wait); 595 wake_up_interruptible(&port->port.delta_msr_wait);
599 spin_unlock_irqrestore(&priv->lock, flags); 596 spin_unlock_irqrestore(&priv->lock, flags);
600exit: 597exit:
601 retval = usb_submit_urb(urb, GFP_ATOMIC); 598 retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -783,57 +780,6 @@ static void mct_u232_unthrottle(struct tty_struct *tty)
783 } 780 }
784} 781}
785 782
786static int mct_u232_ioctl(struct tty_struct *tty,
787 unsigned int cmd, unsigned long arg)
788{
789 DEFINE_WAIT(wait);
790 struct usb_serial_port *port = tty->driver_data;
791 struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port);
792 struct async_icount cnow, cprev;
793 unsigned long flags;
794
795 dev_dbg(&port->dev, "%s - cmd = 0x%x\n", __func__, cmd);
796
797 switch (cmd) {
798
799 case TIOCMIWAIT:
800
801 dev_dbg(&port->dev, "%s TIOCMIWAIT", __func__);
802
803 spin_lock_irqsave(&mct_u232_port->lock, flags);
804 cprev = port->icount;
805 spin_unlock_irqrestore(&mct_u232_port->lock, flags);
806 for ( ; ; ) {
807 prepare_to_wait(&port->delta_msr_wait,
808 &wait, TASK_INTERRUPTIBLE);
809 schedule();
810 finish_wait(&port->delta_msr_wait, &wait);
811 /* see if a signal did it */
812 if (signal_pending(current))
813 return -ERESTARTSYS;
814
815 if (port->serial->disconnected)
816 return -EIO;
817
818 spin_lock_irqsave(&mct_u232_port->lock, flags);
819 cnow = port->icount;
820 spin_unlock_irqrestore(&mct_u232_port->lock, flags);
821 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
822 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
823 return -EIO; /* no change => error */
824 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
825 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
826 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
827 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
828 return 0;
829 }
830 cprev = cnow;
831 }
832
833 }
834 return -ENOIOCTLCMD;
835}
836
837module_usb_serial_driver(serial_drivers, id_table); 783module_usb_serial_driver(serial_drivers, id_table);
838 784
839MODULE_AUTHOR(DRIVER_AUTHOR); 785MODULE_AUTHOR(DRIVER_AUTHOR);