summaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorBjørn Mork <bjorn@mork.no>2012-07-27 01:11:43 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-08-10 20:51:43 +0200
commit032129cb03df196c4216a82295e6555539da4ce7 (patch)
tree8a48ac257883a949d4b953e5cdbc139bfb7684b0 /drivers/usb
parentusb: serial: prevent suspend/resume from racing against probe/remove (diff)
downloadlinux-032129cb03df196c4216a82295e6555539da4ce7.tar.xz
linux-032129cb03df196c4216a82295e6555539da4ce7.zip
usb: usb_wwan: resume/suspend can be called after port is gone
We cannot unconditionally access any usb-serial port specific data from the interface driver. Both supending and resuming may happen after the port has been removed and portdata is freed. Treat ports with no portdata as closed ports to avoid a NULL pointer dereference on resume. No need to kill URBs for removed ports on suspend, avoiding the same NULL pointer reference there. Signed-off-by: Bjørn Mork <bjorn@mork.no> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/usb_wwan.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index 7d0811335b9a..6855d5ed0331 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -602,6 +602,8 @@ static void stop_read_write_urbs(struct usb_serial *serial)
for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i];
portdata = usb_get_serial_port_data(port);
+ if (!portdata)
+ continue;
for (j = 0; j < N_IN_URB; j++)
usb_kill_urb(portdata->in_urbs[j]);
for (j = 0; j < N_OUT_URB; j++)
@@ -700,7 +702,7 @@ int usb_wwan_resume(struct usb_serial *serial)
/* skip closed ports */
spin_lock_irq(&intfdata->susp_lock);
- if (!portdata->opened) {
+ if (!portdata || !portdata->opened) {
spin_unlock_irq(&intfdata->susp_lock);
continue;
}