diff options
author | Johan Hovold <jhovold@gmail.com> | 2013-03-21 07:37:17 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-03-25 16:52:24 -0400 |
commit | 0c61337138763cb24901f394306715019f3272a6 (patch) | |
tree | f820e43ff117d66033275714ccb55c61057fa7e1 /drivers/usb | |
parent | 8c1a07ff7f28549881db0885074feb3e02b07ddb (diff) |
USB: mos7840: 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>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/serial/mos7840.c | 48 |
1 files changed, 2 insertions, 46 deletions
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 92feae6e8851..f0b4e5c01e13 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -219,7 +219,6 @@ struct moschip_port { | |||
219 | char open; | 219 | char open; |
220 | char open_ports; | 220 | char open_ports; |
221 | wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ | 221 | wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ |
222 | int delta_msr_cond; | ||
223 | struct usb_serial_port *port; /* loop back to the owner of this object */ | 222 | struct usb_serial_port *port; /* loop back to the owner of this object */ |
224 | 223 | ||
225 | /* Offsets */ | 224 | /* Offsets */ |
@@ -413,8 +412,7 @@ static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr) | |||
413 | if (new_msr & MOS_MSR_DELTA_RI) | 412 | if (new_msr & MOS_MSR_DELTA_RI) |
414 | icount->rng++; | 413 | icount->rng++; |
415 | 414 | ||
416 | mos7840_port->delta_msr_cond = 1; | 415 | wake_up_interruptible(&port->port->port.delta_msr_wait); |
417 | wake_up_interruptible(&port->port->delta_msr_wait); | ||
418 | } | 416 | } |
419 | } | 417 | } |
420 | 418 | ||
@@ -2113,9 +2111,6 @@ static int mos7840_ioctl(struct tty_struct *tty, | |||
2113 | struct usb_serial_port *port = tty->driver_data; | 2111 | struct usb_serial_port *port = tty->driver_data; |
2114 | void __user *argp = (void __user *)arg; | 2112 | void __user *argp = (void __user *)arg; |
2115 | struct moschip_port *mos7840_port; | 2113 | struct moschip_port *mos7840_port; |
2116 | unsigned long flags; | ||
2117 | struct async_icount cnow; | ||
2118 | struct async_icount cprev; | ||
2119 | 2114 | ||
2120 | if (mos7840_port_paranoia_check(port, __func__)) | 2115 | if (mos7840_port_paranoia_check(port, __func__)) |
2121 | return -1; | 2116 | return -1; |
@@ -2141,46 +2136,6 @@ static int mos7840_ioctl(struct tty_struct *tty, | |||
2141 | case TIOCSSERIAL: | 2136 | case TIOCSSERIAL: |
2142 | dev_dbg(&port->dev, "%s TIOCSSERIAL\n", __func__); | 2137 | dev_dbg(&port->dev, "%s TIOCSSERIAL\n", __func__); |
2143 | break; | 2138 | break; |
2144 | |||
2145 | case TIOCMIWAIT: | ||
2146 | dev_dbg(&port->dev, "%s TIOCMIWAIT\n", __func__); | ||
2147 | spin_lock_irqsave(&port->lock, flags); | ||
2148 | cprev = port->icount; | ||
2149 | spin_unlock_irqrestore(&port->lock, flags); | ||
2150 | while (1) { | ||
2151 | /* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */ | ||
2152 | mos7840_port->delta_msr_cond = 0; | ||
2153 | wait_event_interruptible(port->delta_msr_wait, | ||
2154 | (port->serial->disconnected || | ||
2155 | mos7840_port-> | ||
2156 | delta_msr_cond == 1)); | ||
2157 | |||
2158 | /* see if a signal did it */ | ||
2159 | if (signal_pending(current)) | ||
2160 | return -ERESTARTSYS; | ||
2161 | |||
2162 | if (port->serial->disconnected) | ||
2163 | return -EIO; | ||
2164 | |||
2165 | spin_lock_irqsave(&port->lock, flags); | ||
2166 | cnow = port->icount; | ||
2167 | spin_unlock_irqrestore(&port->lock, flags); | ||
2168 | |||
2169 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && | ||
2170 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) | ||
2171 | return -EIO; /* no change => error */ | ||
2172 | |||
2173 | if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || | ||
2174 | ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || | ||
2175 | ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || | ||
2176 | ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { | ||
2177 | return 0; | ||
2178 | } | ||
2179 | cprev = cnow; | ||
2180 | } | ||
2181 | /* NOTREACHED */ | ||
2182 | break; | ||
2183 | |||
2184 | default: | 2139 | default: |
2185 | break; | 2140 | break; |
2186 | } | 2141 | } |
@@ -2527,6 +2482,7 @@ static struct usb_serial_driver moschip7840_4port_device = { | |||
2527 | .break_ctl = mos7840_break, | 2482 | .break_ctl = mos7840_break, |
2528 | .tiocmget = mos7840_tiocmget, | 2483 | .tiocmget = mos7840_tiocmget, |
2529 | .tiocmset = mos7840_tiocmset, | 2484 | .tiocmset = mos7840_tiocmset, |
2485 | .tiocmiwait = usb_serial_generic_tiocmiwait, | ||
2530 | .get_icount = usb_serial_generic_get_icount, | 2486 | .get_icount = usb_serial_generic_get_icount, |
2531 | .port_probe = mos7840_port_probe, | 2487 | .port_probe = mos7840_port_probe, |
2532 | .port_remove = mos7840_port_remove, | 2488 | .port_remove = mos7840_port_remove, |