diff options
author | xiao jin <jin.xiao@intel.com> | 2014-05-26 13:23:13 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-05-27 18:04:05 -0400 |
commit | db0904737947d509844e171c9863ecc5b4534005 (patch) | |
tree | 903fdf8c6fec1f0fd4a6462c30dea70c9eba40e7 /drivers/usb/serial/usb_wwan.c | |
parent | 496969c64a618579f085a87310bc904eb190a71d (diff) |
USB: usb_wwan: fix urb leak in write error path
When enable usb serial for modem data, sometimes the tty is blocked
in tty_wait_until_sent because portdata->out_busy always is set and
have no chance to be cleared.
We find a bug in write error path. usb_wwan_write set portdata->out_busy
firstly, then try autopm async with error. No out urb submit and no
usb_wwan_outdat_callback to this write, portdata->out_busy can't be
cleared.
This patch clear portdata->out_busy if usb_wwan_write try autopm async
with error.
Fixes: 383cedc3bb43 ("USB: serial: full autosuspend support for the
option driver")
Signed-off-by: xiao jin <jin.xiao@intel.com>
Signed-off-by: Zhang, Qi1 <qi1.zhang@intel.com>
Reviewed-by: David Cohen <david.a.cohen@linux.intel.com>
Cc: <stable@vger.kernel.org> # v2.6.32
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/serial/usb_wwan.c')
-rw-r--r-- | drivers/usb/serial/usb_wwan.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index b078440e822f..47ad7550c5a6 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c | |||
@@ -228,8 +228,10 @@ int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
228 | usb_pipeendpoint(this_urb->pipe), i); | 228 | usb_pipeendpoint(this_urb->pipe), i); |
229 | 229 | ||
230 | err = usb_autopm_get_interface_async(port->serial->interface); | 230 | err = usb_autopm_get_interface_async(port->serial->interface); |
231 | if (err < 0) | 231 | if (err < 0) { |
232 | clear_bit(i, &portdata->out_busy); | ||
232 | break; | 233 | break; |
234 | } | ||
233 | 235 | ||
234 | /* send the data */ | 236 | /* send the data */ |
235 | memcpy(this_urb->transfer_buffer, buf, todo); | 237 | memcpy(this_urb->transfer_buffer, buf, todo); |