diff options
author | Johan Hovold <jhovold@gmail.com> | 2013-03-21 07:37:13 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-03-25 16:50:53 -0400 |
commit | 128434ab5607c6bccf385765e94382cedd3d06fa (patch) | |
tree | e1c3ad08668e66fd86a76e240edc012c88713c98 | |
parent | 468c740ee5372b74e9d9bd4d7ec2d81d44e67f2d (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.c | 58 |
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); | |||
57 | static int mct_u232_tiocmget(struct tty_struct *tty); | 56 | static int mct_u232_tiocmget(struct tty_struct *tty); |
58 | static int mct_u232_tiocmset(struct tty_struct *tty, | 57 | static int mct_u232_tiocmset(struct tty_struct *tty, |
59 | unsigned int set, unsigned int clear); | 58 | unsigned int set, unsigned int clear); |
60 | static int mct_u232_ioctl(struct tty_struct *tty, | ||
61 | unsigned int cmd, unsigned long arg); | ||
62 | static void mct_u232_throttle(struct tty_struct *tty); | 59 | static void mct_u232_throttle(struct tty_struct *tty); |
63 | static void mct_u232_unthrottle(struct tty_struct *tty); | 60 | static 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); |
600 | exit: | 597 | exit: |
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 | ||
786 | static 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 | |||
837 | module_usb_serial_driver(serial_drivers, id_table); | 783 | module_usb_serial_driver(serial_drivers, id_table); |
838 | 784 | ||
839 | MODULE_AUTHOR(DRIVER_AUTHOR); | 785 | MODULE_AUTHOR(DRIVER_AUTHOR); |