aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Mork <bjorn@mork.no>2012-07-26 19:11:43 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-08-10 14:51:43 -0400
commit032129cb03df196c4216a82295e6555539da4ce7 (patch)
tree8a48ac257883a949d4b953e5cdbc139bfb7684b0
parentd5fd650cfc7ffeca4af0da939293c8e7a5aa7c36 (diff)
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>
-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)
602 for (i = 0; i < serial->num_ports; ++i) { 602 for (i = 0; i < serial->num_ports; ++i) {
603 port = serial->port[i]; 603 port = serial->port[i];
604 portdata = usb_get_serial_port_data(port); 604 portdata = usb_get_serial_port_data(port);
605 if (!portdata)
606 continue;
605 for (j = 0; j < N_IN_URB; j++) 607 for (j = 0; j < N_IN_URB; j++)
606 usb_kill_urb(portdata->in_urbs[j]); 608 usb_kill_urb(portdata->in_urbs[j]);
607 for (j = 0; j < N_OUT_URB; j++) 609 for (j = 0; j < N_OUT_URB; j++)
@@ -700,7 +702,7 @@ int usb_wwan_resume(struct usb_serial *serial)
700 702
701 /* skip closed ports */ 703 /* skip closed ports */
702 spin_lock_irq(&intfdata->susp_lock); 704 spin_lock_irq(&intfdata->susp_lock);
703 if (!portdata->opened) { 705 if (!portdata || !portdata->opened) {
704 spin_unlock_irq(&intfdata->susp_lock); 706 spin_unlock_irq(&intfdata->susp_lock);
705 continue; 707 continue;
706 } 708 }